RegExp.test()为同一个str返回不同的结果,具体取决于调用它的方式(where?)

时间:2012-11-27 14:48:59

标签: javascript jquery regex

我刚刚注意到一个奇怪的JS行为导致一个恼人的错误..

基本上,我在if语句中使用RegExp对象(.test()方法)测试str。 对于测试的相同字符串,如果在我的代码中我只有一个if,则regexp.test()返回true并且它可以很好地进入if。

问题是如果我有一个其他的(我需要它),出于某种原因,对于相同的str测试,regexp.test()返回false并转到else ...

这是什么行为?

我已经进行了很多测试......

TL / DR:对于在同一个RegExp上测试的相同字符串,如果只有一个IF语句,则regexp.test()返回true,但如果我有一个else,则返回false。

some code

我忘了说所有单词都没有出现这个错误..

http://jsfiddle.net/zrwkU/13/

在文本字段中输入“armoire”一词,然后按Enter键。 这个jsfiddle有“else return false”,没有任何反应。

删除searchDeeper函数中的“else return false”(如果(regexp.test(tests)){)并再次进行测试。现在它进入了if和一个msgbox弹出窗口。

2 个答案:

答案 0 :(得分:22)

/regex/g.lastIndex = 0

对于设置了全局'g'标志的模式,使用RegExp方法; test()exec()跟踪它们匹配的最后位置,并将此整数存储在RegExp对象的lastIndex属性中。当每个匹配应用于任何字符串时,此索引会自动前进。请注意,test()exec()都表现出这种方式。一旦匹配失败,最后一个索引属性将自动重置为零。你也可以自己手动将它重置为零,看起来这就像你需要做的那样。添加一行以重置RegExp.lastIndex,如下所示:

if (regexp != null){
    regexp.lastIndex = 0;
    if (regexp.test(tested)){
        alert('ok');
        regexp.lastIndex = 0;
        var res = regexp.exec(tested);
        tested = tested.replace(res, '<span class="underlined">' + res + '</span>');
    }else{
        return false;
    }
}

这是另一种解决方案,它完全避免了这个 last-index-issue 。它使用String.match()方法代替:

A String.match()替代方案:

if (regexp != null){
    if (tested.match(regexp)){
        alert('ok');
        regexp.lastIndex = 0;
        var res = tested.match(regexp);
        tested = tested.replace(res, '<span class="underlined">' + res + '</span>');
    }else{
        return false;
    }
}

答案 1 :(得分:2)

我认为唯一的问题是你在哪里

}else{
    return false;
}

你真正想要的是

}else{
   continue;
}

以继续外循环for (var k in cats){

根据此更新:http://jsfiddle.net/zrwkU/14/

通过解释 - 使用您的代码,只要对test的调用失败,那就是您使用return false跳转的方法。通过更改为continue,您还可以继续“深入搜索”其他类别。