js中正则表达式的功能非常强大,匹配、替换、查找无所不能。利用好正则可以达到事半功倍的效果。
基础内容不再赘述,这里只聊一些比较容易被忽略的技巧。
匹配数量
{n}
匹配n次
{n,}
匹配大于等于n次
{n,m}
匹配大于等于n次,小于等于m次
*
匹配前一个表达式0次或多次,相当于{0,}
+
匹配前面一个表达式1次或者多次,相当于{1,}
?
匹配前面一个表达式0次或者1次。相当于 {0,1}。跟在* + ? {} 后,将会使量词变为非贪婪的。
字符集
[abc]
就是一个字符集,表示匹配方括号中的任意字符。
也可以使用"-"指定一个范围如:[a-c]
等同于[abc]
对于(.)(*)等特殊符号,在字符集中不再具有特殊含义,只代表本身字符。(可以不进行转义)
注意:字符集中没有顺序限制,如下示例
/[.a-z]+/.test('abc.d.ef')
为true
反向字符集
[^abc]
反向字符集,匹配没有包含方括号中的字符。
模式匹配
1、==(x)==
(x)
,匹配x并且记住匹配项。使用如下:
/(abc) (def) \1 \2/
上面的正则中(foo) (bar)匹配并记住字符串“abc def abc def”中前两个单词,模式中的\1 \2 是匹配字符串中的后两个单词。
\1 \2 \n 这种方式用在正在表达式的匹配环节。
像 2、$n 用在正则表达式替换环节。例如:
'abc def'.replace( /(...) (...)/, '$2 $1' )
2、==(?:x)==
(?:x)
,匹配x但是不记住匹配项,也可以叫做非捕获括号。
如/abc{1,2}/
,匹配数量只会针对于最后一个字母"c"生效。在使用了非捕获括号后
/(?:abc){1,2}/
,这时匹配数量会针对"abc"生效。
3、==x(?=y)==
x(?=y)
,匹配'x',并且只有在'x'后面跟着'y'时匹配。也叫做先行断言。
/Java(?=Script)/
,可能会匹配到'Java',条件是当它后面跟着'Script'时。
需要注意的是,‘Script’不是匹配结果的一部分。
例如:
/Java(?=Script)/.test('JavaScript') // true
/Java(?=Script)/.test('JavaEE') // false
4、==(?<=y)x==
(?<=y)x
,匹配'x',并且只有在'x'前面是'y'时匹配。也叫做后行断言。
/(?<=Java)Script/
,会匹配到' Script ',只有在它前面是' Java '时。
同上‘Java’也不是匹配结果的一部分。
例如:
/(?<=Java)Script/.test('JavaScript') // true
/(?<=Java)Script/.test('TypeScript') // false
5、==x(?!y)==
x(?!y)
,仅仅当'x'后面不跟着'y'时匹配'x'。也叫做正向否定查找。
例如:
/Java(?!Script)/.test('JavaScript') //false
/Java(?!Script)/.test('JavaEE') //true
6、==(?<!y)x==
(?<!y)x
,仅仅当x前面不跟着y时匹配x。也叫做反向否定查找。
例如:
/(?<!Java)Script/.test('JavaScript') //false
/(?<!Java)Script/.test('TypeScript') //true
边界匹配
==\b==
\b 匹配一个词的边界。一个词的边界就是一个词不被另外一个字符跟随的位置或者没有其他字符在其前面的位置。一个匹配的词的边界的内容的长度是0。
如字符串"script"
/\bs/
,匹配“script”中的‘s’;
/cr\b/
,并不匹配"script"中的'cr',因为'cr'被一个字符'i'紧跟着。
/pt\b/
,匹配"script"中的'pt',因为'pt'是这个字符串的结束部分。这样他没有被一个字符紧跟着。
/\w\b\w/
,将不能匹配任何字符串,因为在一个单词中间的字符永远也不可能同时满足没有字符跟随和有字符跟随两种情况。
==\B==
与之用法对应的是\B
,匹配非单词边界。
如字符串"pest text"
/t\B../
,匹配到的是'tex'。