一直以为已经懂了,这两天项目中有相关需求并实际使用断言后发现,并没有。
这里将断言查分成最基本的形态来看,例如需求是利用断言匹配 'a1' 字符串。(其实没有必要用正向断言,直接用 /a1/ 就可以匹配出来。这里主要是为了更直观的了解正向断言和反向断言。)
原来的认知,此时应该可以匹配出来,但结果却是null。
真正的原因是断言不会消耗字符串,所以正则后面的1还是从字符串a处检查,所以结果为null。
如果还不明白的话,可以这样看,正则匹配的同时有一个指针,字符串也会出现一个匹配指针,两者初始指向都是起始位置。
假如对应的正则是:
/a1/.exec('a1')
它的匹配方式是这样的:正则a匹配到字符串a时,正则指针位置向后移动,字符串的指针也会向后移动,此时正则指针的位置是1,字符串指针位置也是1。最后正则中的1匹配字符串中的1。完成匹配过程,找到a1字符串。
假如对应的正则是:
/(?=a)1/.exec('a1')
它的匹配方式是这样的:正则中的断言部分匹配到a,正则指针向后移动,字符串指针不移动,此时正则指针的位置是数字1,字符串指针还是指向a(断言不消耗字符串)。两者对比后不相同,所以结果为null。
接下来介绍反向断言,上面的例子用反向断言就可以出结果了,不会出现null。
/(?<=a)1/.exec('a1') // 输出 ['1', index: 1, input: 'a1', groups: undefined]
它的匹配方式是这样的:先匹配正则中的1,在回头匹配断言中的内容。
结论:
正向断言和反向断言的区别在于断言和正则普通内容的判断顺序,正向断言会先判断断言中的内容,然后才是普通内容。反向断言先判断普通内容,最后判断断言内容。
正向和反向的实际意义在于断言不会移动正则指针,有时要 匹配但不捕获内容 又要 考虑到断言指针的工作方式 这时就可以灵活使用正向和反向两种断言