JS正则表达式跳过了每个其他匹配

6

我在JS中看到了一些奇怪的RegExp对象行为。我尝试将查询字符串与搜索自动完成功能的单词开头匹配。当遍历名称数组并返回匹配项时,正则表达式仅匹配每个预期匹配项的另一半。

var words = [
                "catherine",
                "caterpillar", 
                "nice catch", 
                "fat cat", 
                "catalina"
            ],
            re = new RegExp('\\bcat', 'gi'),
            matches = [],
            results, i;

for (i=0; i<words.length; i++) {
    if (re.exec(words[i])) {
        matches.push(words[i]);
    }
}

console.log(matches);

这段代码返回["catherine", "nice catch", "catalina"]。无论元素的顺序如何,行为都是相同的。如果我在每次迭代中重新创建这个RegExp对象(例如,在for循环内部使用re = new RegExp('\\bcat','gi')),它就像预期的那样返回所有数组项,但我真的不想在每次迭代中都这样做。
我对正则表达式不太熟悉 - 这是我的正则表达式有问题吗?我是否忘记了分隔符或其他什么东西?还是这只是另一个JS的怪癖?
2个回答

10
当您在 RegExp 对象上调用 exec 时,它会维护一个 lastIndex 属性,该属性包含正则表达式匹配字符串的前一个索引。下次使用 exec 尝试进行匹配时,它将仅从索引 "lastIndex + 1" 开始查找,即使您正在搜索不同的字符串也是如此。
为了防止这种情况发生,您可以在每次循环迭代中将 re.lastIndex 设置为 -1,或者在创建 RegExp 时删除全局标志。

这个人给出了一个非常好的解释:http://blog.thatscaptaintoyou.com/strange-behavior-of-the-global-regex-flag/ - numbers1311407

1

1
我已经删除了我的答案,因为这是正确的答案。方法与此无关。请参见http://jsfiddle.net/2m5dT/. - Andrew Cheong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接