Skip to content
On this page

09. 连续两次正则测试结果不一样

解释

执行下面的代码,会出乎意料,两次 test 正则匹配的结果不一样。

js
const r = /foo/g
let s = 'foobar'
r.test(s) // true
r.test(s) // false
1
2
3
4

这是因为当给正则式加了 g 标志后,test 方法会修改正则对象的 lastIndex 属性的值。初始状态下 lastIndex0,每次执行 test 后,lastIndex 会被设置为上一次匹配结果的末尾位置的索引,直到字符串末尾,又变为 0每次正则匹配都从 lastIndex 处开始匹配。

js
const re = /foo/g
let str = 'foo-foo-foo'
re.lastIndex // 0
re.test(str) // true
re.lastIndex // 3
re.test(str) // true
re.lastIndex // 7
re.test(str) // true
re.lastIndex // 11
re.test(str) // false
re.lastIndex // 0
re.test(str) // true
1
2
3
4
5
6
7
8
9
10
11
12

解决

解释了这种现象之后,解决方法如下:

  • 需要用到连续匹配的情况,例如循环里匹配,每次重置正则属性 lastIndex=0
  • 去掉 g 标志,在非全局匹配模式下,lastIndex 的值始终为 0

总结

  1. 所有的正则表达式都有一个 lastIndex 属性,用于记录上一次匹配结束的位置。如果不是全局匹配模式,那 lastIndex 的值始终为 0,在匹配过一次后,将会停止匹配。
  2. 全局模式下,testexec 方法都会修改 lastIndex 的值。