本文已参与「新人创作礼」活动,一起开启掘金创作之路。
创建正则
字面量和实列两种创建方法
var reg = /正则表达式/修饰符var reg = new RegExp(正则表达式, 修饰符)
var reg = /123123123aaa.*/g
// 或
var val = '匹配'
var reg = new RegExp('123123123aaa.*','g');
修饰符
i忽略大小写匹配m多行匹配g全局匹配 修饰符可以写多个,如/1234aaaa/img
常用元字符
.匹配除\n以外的任何字符\w匹配数字、字母、下划线\W匹配非数字、字母、下划线\s匹配空白字符(空格、Tab(制表符)、换行)\S匹配非空白字符\d匹配数字\D匹配非数字字符
常用元字符
\n换行符^字符串的开始$字符串的结束\b匹配单词的开始或结束(开头、空格、-、.等都表示单词的结束)\B匹配非单词的开始或结束\或者()分组(详见下方)[]字符类(详见下方)
数量元字符
*重复0-n次+重复1-n次x?重复0-1次{x}重复x次(x为固定值){x,y}重复x-y次
贪婪与惰性模式
- 贪婪模式: 如果符合要求就会一直往后匹配,一直到无法匹配成功
- 惰性模式: 匹配到合适的内容后就不会终止
贪婪模式和惰性模式用白话说就是一个是能匹配多就匹配多,一个是能少匹配就少匹配
正则默认为贪婪模式,如果想使用惰性模式,就要在数量元字符的后边加上?举个栗子:
var val = '12345678asd';
console.log(/.*/.exec(a)[0]) // "123456789"
console.log(/.*?/.exec(a)[0]) // ""
console.log(/.+/.exec(a)[0]) // "123456789"
console.log(/.+?/.exec(a)[0]) // "1"
console.log(/\d{1,100}/.exec(a)[0]) // "123456789"
console.log(/\d{1,100}?/.exec(a)[0]) // "1"
\转义字符
如果要匹配具有特殊意义的特殊符号或者使用某些元字符,需要使用\来转义区分
\*匹配字符"*"(单独的*代表*前的字符重复0-n次)\.匹配字符"."(单独的.匹配除\n以外的任何字符)\w匹配数字、字母、下划线(单独的w匹配字母w)- ...
字符类
[]字符类
- 字符类用于匹配某一范围的字符
[]中匹配到的内容只能是一个字符
比如要查找数字,我们可以用\d,也可以用字符类[0-9]一样生效在字符类中,-代表着取值选择一个取值范围范围,如果想要匹配字符串-,要加转义符[\-]
[0-15]匹配的是0-1和5,并不是0、1、2、3、4...15
[aaaassddasdasddsda]和[asd]匹配的都是a或s或d
字符类中,^代表着非,是指匹配非[^内容]中的内容
var reg = /a[dp]c/ // 匹配adc或apc
var reg = /[a-zA-Z0-9_]/ // 匹配数字字母下划线
var reg = /[^a-zA-Z0-9_]/ // 匹配非数字字母下划线
分组
()可以进行对内容的范围选择,捕获等
(123|132|321|312) 表示不论是123、132、321、312都可以匹配
(123)? 这时的?是对123这一组数据应用的,代表着出现一次123或者不出现123
1.在exec中使用可以获得()中的内容
举个栗子:
var a = "123456789"
var val = /34567/.exec(a)
console.log(val[0]) // "34567"
console.log(val[1]) // undefined
var val2 = /34(56)7/.exec(a)
console.log(v2[0]) // "34567"
console.log(v2[1]) // "56"
2. 当正则表达式执行了test()方法或者exec(),且 该正则表达式中包含分组,则分组中与字符串匹配的内容,会被保存下来。
提取正则表达式中的内容最多提取9个()中的内容
RegExp.$1————RegExp.$9
举个栗子:
var a = "123456789"
/(2)(3)((4)(5))6789/.test(a)
console.log(RegExp.$1) // "2"
console.log(RegExp.$2) // "3"
console.log(RegExp.$3) // "45"
console.log(RegExp.$4) // "4"
console.log(RegExp.$5) // "5"
console.log(RegExp.$6) // "" // 因为没有第六个括号,所以是空
3. 在replace中使用()可以通过$n来取得括号中的内容
举...:
var a = "123456789"
a.replace(/2345(67)8/, '这是替换的文字$1这是替换的文字')
// "1这是替换的文字67这是替换的文字"
replace补充,其他字符串匹配方式:
$n:匹配成功的第n组内容,n是从1开始的自然数。(上边例子的那个)$&:匹配的子字符串。$’:匹配结果前面的文本。(ps:’是``````,就是键盘数字键1左边那个,有大佬能告诉我怎么合规的打出来一个``吗)$':匹配结果后面的文本。$$:指代美元符号$。
断言
断言可以帮助我们查找某些内容时,对内容前和内容后的信息作为判断(但并不包括这些内容)(把内容前或后的信息作为判断依据但结果不包括这些内容,所以也被称为零宽断言)
比如我们要在字符串我是小明我是小王我是小绿我是小猪我啥也不是把小明前的我是改为我不是,就可以使用零宽正先行断言(?=X)(X代表需要被匹配但不被包括的内容)
var str = "我是小明我是小王我是小绿我是小猪我啥也不是"
var reg = /我是(?=小明)/
console.log(str.replace(reg,'我不是'))
// "我不是小明我是小王我是小绿我是小猪我啥也不是"
可以看到,(?=小明)中的小明没有被替换掉,但是起到了匹配的作用,这就是断言的用处
断言的写法
VVV(?=XXX)零宽正先行断言————只有在断言XXX在VVV的后边时,才会继续匹配VVV(?!XXX)零宽负先行断言————只有在断言XXX不在VVV的后边时,才会继续匹配(?<=XX)VVV零宽正后发断言————只有在断言XX在VVV的前边时,才会继续匹配(?<!XX)VVV零宽负后发断言————只有在断言XX不在VVV的前边时,才会继续匹配
需要注意
- 断言不占用字符,不被包括在内容中
- 断言一定要写在括号中
() - 后发断言以前在js中不支持