PS: 浏览此篇文章前须要具有以下学问:
- 正则表达式的基础语法
- String.prototype.replace()
- String.prototype.match()
捕捉组(capturing group)是正则表达式里比较常常运用,也是比较主要的观点,我个人以为控制这部份的学问是非常主要的。
这篇文章内容不会很深切,然则只管做到简朴易懂又周全。接下来的内容主如果缭绕以下7个点:
1: () 捕捉组
2: (?:) non capturing group
3: (?=) positive lookahead
4: (?!) negative lookahead
5: (?<=) positive lookbehind
6: (?<!) negative lookbehind
7: (?=), (?!), (?<=), (?<!)的捕捉
1: () 捕捉组
/go+/
以上的正则表达式示意一个字母g背面跟上一个也许多个字母o,他能婚配go
也许goooo
。然则如果我们想+不只是运用到字母o上,而是运用到go这个团体上怎么办呢?要领就是给go加括号:
/(go)+/
为了全局婚配以及不斟酌大小写,我们接下来会给我们的正则加上ig,这两个flag:
let reg = /(go)+/ig;
'go is g gogo'.match(reg); //["go", "gogo"]
在上面的例子内里(go)就形成了一个捕捉组(capturing group)。接下来看一个运用捕捉组的例子来加深对它的明白:
let reg = /(\d{2}).(\d{2}).(\d{4})/;
let originString = '10.25.2017';
reg.test(originString); //true
RegExp.$1; //10
RegExp.$2; //25
RegExp.$2; //2017
在上面这个例子里,我们有三组括号,形成了三个捕捉组,正则表达式(在javaScript里就是我们的RegExp)会缓存捕捉组所婚配的串,以$n
示意,n就代表这第几个捕捉组。
如果如今我们有一个需求:把显现花样为 10.25.2017 的时刻改成 2017-10-25 花样。
我们晓得String的replace()要领常常和正则表达式一同运用。在replace()要领里,我们能够直接运用捕捉组的效果:
let reg = /(\d{2}).(\d{2}).(\d{4})/;
let originString = '10.25.2017';
let newString = originString.replace(reg, '$3-$1-$2');
console.log(newString);//"2017-10-25"
2: (?:) non capturing group 非捕捉型分组
有的时刻我们能够只想婚配分组,然则并不想缓存(不想捕捉)婚配到的效果,就能够在我们的分组形式前面加上?:
。比方上面的时刻的例子,我们不想捕捉第一个分组的效果,就能够这么做:
let reg = /(?:\d{2}).(\d{2}).(\d{4})/;
let originString = '10.25.2017';
reg.test(originString); //true
RegExp.$1; //25
RegExp.$2; //2017
originString.match(reg);// ["10.25.2017", "25", "2017", index: 0, input: "10.25.2017", groups: undefined]
从上面的例子能够看出,我们的正则表达式依旧是婚配的(test()的效果依旧为true),然则RegExp.$1不是数字10,而是25,由于我们在第一个括号里加了?:
,10就不会被捕捉。match()的实行效果也会受?:
的影响:match()的效果里不再有‘10’。
3: (?=) positive lookahead 正向前瞻型捕捉
有一个句子:1 apple costs 10€. 我们想要婚配€前面的价钱(这里是一个数字),然则注重不能婚配到句子开首的数字1。这类状况,就能够用到正向前瞻型捕捉:
let reg = /\d+(?=€)/g;
let reg1 = /\d+/g;
let str = '1 apple costs 10€';
str.match(reg); //["10"]
str.match(reg1); //["1", "10"]
上面的例子内里reg1就只须要婚配数字,关于数字背面跟什么并没有请求,所以它能婚配到1,10。然则reg运用了前瞻型婚配,就只能婚配到10。
也许你已能从上面的对照里相识到什么是正向前瞻型捕捉了,意义是:
/x(?=y)/ 婚配x, 然则必须在x的【背面】【是】y的状况下
4: (?!) negative lookahead 负向前瞻型捕捉
上面我们相识了什么是正向前瞻型婚配,从字面意义也能猜出来负向前瞻型捕捉就是:
/x(?!y)/ 婚配x, 然则必须在x的【背面】【不是】y的状况下
比方下面的例子,我们要婚配数字1,而不要€前面的2,就能够用到?!
:
let reg = /\d+(?!€)/g;
let str = '1 apple costs 2€';
str.match(reg); ['1']
5: (?<=) positive lookbehind 正向后顾型捕捉
后顾型和前瞻型恰好相反,意义就是:
/(?<=y)x/ 婚配x, 然则只在【前面】【有】y的状况下
来看一个例子:
let str = "1 turkey costs $2";
console.log( str.match(/(?<=\$)\d+/g) ); //["2"]
这里的请求是前面有$的数字,所以这里婚配到了数字2,而没有1.
6: (?<!) negative lookbehind 负向后顾型捕捉
负向就是与正向相反,那末负向后顾型捕捉就是:
/(?<=y)x/ 婚配x, 然则只在【前面】【没有】y的状况下
来看一个例子:
let str = "1 turkey costs $2";
console.log( str.match(/(?<!\$)\d+/g) ); //['1']
7: (?=), (?!), (?<=), (?<!)的捕捉
默许状况下上面的前瞻后顾4种都是默许不婚配捕捉组内里的内容的,也就是不婚配括号里的前提的。比方我们的正向前瞻/d+(?=€)/g,只会婚配到数字,并不会婚配到€。如果我们想要也婚配到€怎么办呢?答案就是给€也包上一个括号:
let str = "1 turkey costs 2€";
let reg = /\d+(?=(€))/;
str.match(reg); //["2", "€", index: 15, input: "1 turkey costs 2€", groups: undefined]
如许就婚配到了数字2和它背面的€。
下面再来看看后顾型:
let str = "1 turkey costs $2";
let reg = /(?<=(\$|£))\d+/;
console.log( str.match(reg) ); //["2", "$", index: 16, input: "1 turkey costs $2", groups: undefined]
须要迥殊注重到的一点是,关于后顾型,虽然前提在婚配项的前面,然则婚配出来的效果递次依旧是前提在婚配项的背面。所以这里match()出来的效果是2在$的前面。
PS:截止到目前为止(ES2015),JavaScript还不支撑后顾型婚配,就是说(?<=), (?<!)这两种是不支撑的。如果你在webStorm内里运用能够会获得error:look-behind groups are not supported in this regex dialect。好消息是ES2018已对其进行了支撑,能够参考:http://2ality.com/2017/05/reg…