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

Mar*_*uis 7 javascript regex jquery

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

基本上,我在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
Run Code Online (Sandbox Code Playgroud)

我忘了说所有的话都不会发生这个错误..

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

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

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

rid*_*ner 25

/regex/g.lastIndex = 0

对于具有全局'g'标志设置的模式,RegExp方法; test()exec()跟踪它们匹配的最后一个位置,并将此整数存储在RegExp对象的:lastIndexproperty中.当每个匹配应用于任何字符串时,此索引会自动前进.请注意这两个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是另一个完全避免这个最后索引问题的解决方案.它使用的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 10 倍很多,因为我花了很多时间来搜索几乎相同问题的根源。上帝祝福你)) (3认同)
  • 在我正在做的事情中,我变得真实然后虚假然后真实。在 regex101 中测试我的字符串时保留了 `g` 修饰符 - 删除 `g` 修饰符解决了我的问题。 (2认同)

Jam*_*iec 1

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

}else{
    return false;
}
Run Code Online (Sandbox Code Playgroud)

你真正想要的是

}else{
   continue;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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