ES6 正则表达式之后行断言

ES6 之前的正则表达式只支持先行断言和先行否定断言,ES2018 引入了 后行断言和后行否定断言

先行断言

先行断言是指: x 只有在 y 前面才匹配,必须写成 /x(?=y)/

/\d+(?=%)/.exec('there are examples of 6% and 8')  // ["6", ...]

先行否定断言指的是,x 只有不在 y 前面才匹配,必须写成 /x(?!y)/

/\d+(?!%)/.exec('there are examples of 6% and 8')  // ["8", ...]

后行断言

后行断言是指 x 只有在 y 后面才匹配,必须写成 /(?<=y)x/

/(?<=\$)\d+/.exec('there are examples of $6 and 8')  // ["6", ...]

后行否定断言指的是,x 只有不在 y 后面才匹配,必须写成 /(?<!y)x/

/(?<!\$)\d+/.exec('there are examples of $6 and 8')  // ["8", ...]

后行断言字符串替换示例:

const reg = /(?<=\$)\d+/g
const str = 'there are examples of $6 and 8'
str.replace(reg, '88')
// there are examples of $88 and 8

后行断言的特点

后行断言的实现,需要先匹配 /(?<=y)x/ 的 x,然后再回到左边,匹配 y 的部分
这种先右后左的执行顺序会导至:

首先,后行断言的组匹配与正常情况下结果不一样

/^(\d+)(\d+)kb$/.exec('1024kb') // ["1024kb", "102", "4", ...]
/(?<=(\d+)(\d+))kb$/.exec('1024kb') // ["kb", "1", "024", ...]

上面代码中,有两个组匹配。正常模式下第一个括号是贪婪模式,第二个括号只能捕获一个字符,所以组匹配的结果是 102 和 4;后行断言模式下,由于执行顺序是从右到左,第二个括号是贪婪模式,第一个括号只能捕获一个字符,所以结果是 1 和 024

其次,后行断言的反斜杠引用,也与通常的顺序相反,必须放在对应的那个括号之前

/(?<=(o)n\1)r/.exec('honor')  // null
/(?<=\1n(o))r/.exec('honor')  // ["r", "o", ...]

上面代码中,如果后行断言的反斜杠引用(\1)放在括号的后面,就不会得到匹配结果,必须放在前面才可以。因为后行断言是先从左到右扫描,发现匹配以后再回过头,从右到左完成反斜杠引用

除特殊说明外本人博客均属原创,转载请注明出处:http://blog.johnhan.cn/blog_1022.html
鄂ICP备17018604号-1  鄂公网安备42060702000030号