鉴于此代码:
var reg = /a/g;
console.log(reg.test("a"));
console.log(reg.test("a"));
我得到了这个结果:
true
false
我不知道这是怎么发生的。我已经在Node.js(v8)和Firefox浏览器中进行了测试。
答案 0 :(得分:24)
要解决此问题,您可以删除g
标记或重置lastIndex
,如
var reg = /a/g;
console.log(reg.test("a"));
reg.lastIndex = 0;
console.log(reg.test("a"));
问题出现是因为test
基于exec
,它在第一个之后查找更多匹配项,如果传递相同的字符串并且存在g
标记。
15.10.6.3
RegExp.prototype.test(string)
#ⓉⓇ采取以下步骤:
- 让匹配是使用 string 作为参数在此
RegExp.prototype.exec
对象上评估RegExp
(15.10.6.2)算法的结果。- 如果匹配不是
醇>null
,则返回true
;否则返回false
。
exec
的关键部分是15.10.6.2的第6步:
6。让global成为使用参数“global”调用R的[[Get]]内部方法的结果 7.如果global为false,则让i = 0。
当i
未重置为0时,exec
(因此test
)不会开始查看字符串的开头。
这对exec
很有用,因为你可以循环来处理每个匹配:
var myRegex = /o/g;
var myString = "fooo";
for (var match; match = myRegex.exec(myString);) {
alert(match + " at " + myRegex.lastIndex);
}
但显然它对test
没那么有用。
答案 1 :(得分:2)
通常选择一个测试来检查某些模式是否匹配,但是全局标志允许您遍历字符串以计算匹配,或者像exec一样,对每个lastIndex执行某些操作。另一个用途是在执行测试之前自己设置rx的lastIndex,以在某些字符索引之前忽略匹配。
var count=0, rx=/\s+/g, rx.lastIndex=100;
while(rx.test(string))count++;