JavaScript中误用/g导致的正则test()无法正确重复执行
如下代码的输出结果会交替输出true, false 并没有按照我们的预期输出结果
var reg = /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/g;
console.log(reg.test('#00f')); // true
console.log(reg.test('#00f')); // false
console.log(reg.test('#00f')); // true
原来这个问题实际上是/g导致的, 因为/g代表全局匹配,所以判断正则时内部是有一个lastIndex来记录最后匹配的位置.当重复调用的时候,会接着上次的lastIndex继续匹配,
一旦未匹配成功了lastIndex会自动归零,所以就很容易理解以上代码的输出结果了,因为第二次输出是以第一次查找的lastInde为起点开始查找的,此时没有找到匹配的字符串,所以lastIndex归零,第三次查找从lastIndex = 0开始查找,所以能够匹配到相应的字符串。
明白了原理解决起来也就很明了了:
1.去掉/g,在不需要/g的情况下不要随意添加/g标识
2.第二次匹配前,手动将lastIndex置0,以上面的例子来说:reg.lastIndex()=0即可.
var reg = /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/;
console.log(reg.test('#00f')); // true
console.log(reg.test('#00f')); // true
console.log(reg.test('#00f')); // true
var reg = /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/g;
console.log(reg.test('#00f')); // true
reg.lastIndex = 0;
console.log(reg.test('#00f')); // true
reg.lastIndex = 0;
console.log(reg.test('#00f')); // true