12

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

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

问题是如果我有一个 else (我需要它),出于某种原因,对于相同的 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 函数( if (regexp.test(tested)){ )中的“else return false”并再次进行测试。现在它进入 if 和 msgbox 弹出窗口。

4

2 回答 2

36

/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;
    }
}

这是另一个完全避免这个最后索引问题的解决方案。它使用以下String.match()方法:

另一种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;
    }
}
于 2012-11-27T15:43:46.487 回答
2

我认为唯一的问题是你有

}else{
    return false;
}

你真正想要的是

}else{
   continue;
}

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

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

通过解释-使用您的代码,一旦调用test失败,就是这样-超出您使用的方法return false。通过更改为 a continue,您也可以继续在其他类别中“更深入地搜索”。

于 2012-11-27T15:49:40.563 回答