javascript RegExp.exec() 偶尔返回 NULL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4724701/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RegExp.exec() returns NULL sporadically
提问by cpak
I am seriously going crazy over this and I've already spent an unproportionate amount of time on trying to figure out what's going on here. So please give me a hand =)
我真的为此发疯了,我已经花了不成比例的时间来试图弄清楚这里发生了什么。所以请帮我一把 =)
I need to do some RegExp matching of strings in JavaScript. Unfortunately it behaves very strangely. This code:
我需要在 JavaScript 中对字符串进行一些 RegExp 匹配。不幸的是,它的行为非常奇怪。这段代码:
var rx = /(cat|dog)/gi;
var w = new Array("I have a cat and a dog too.", "There once was a dog and a cat.", "I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.");
for (var i in w) {
var m = null;
m = rx.exec(w[i]);
if(m){
document.writeln("<pre>" + i + "\nINPUT: " + w[i] + "\nMATCHES: " + m.slice(1) + "</pre>");
}else{
document.writeln("<pre>" + i + "\n'" + w[i] + "' FAILED.</pre>");
}
}
Returns "cat" and "dog" for the first two elements, as it should be, but then some exec()-calls start returning null. I don't understand why.
为前两个元素返回“cat”和“dog”,这是应该的,但随后一些 -exec()调用开始返回null。我不明白为什么。
I posted a Fiddle here, where you can run and edit the code.
我在这里发布了一个 Fiddle ,您可以在其中运行和编辑代码。
And so far I've tried this in Chrome and Firefox.
到目前为止,我已经在 Chrome 和 Firefox 中尝试过这个。
Cheers!
干杯!
/Christofer
/克里斯托弗
采纳答案by SilentGhost
Oh, here it is. Because you're defining your regex global, it matches first cat, and on the second pass of the loop dog. So, basically you just need to reset your regex (it's internal pointer) as well. Cf. this:
哦,它来了。因为您正在定义您的 regex 全局,它首先匹配cat,然后在循环的第二遍匹配dog。所以,基本上你只需要重置你的正则表达式(它是内部指针)。参见 这:
var w = new Array("I have a cat and a dog too.", "I have a cat and a dog too.", "I have a cat and a dog too.", "I have a cat and a dog too.");
for (var i in w) {
var rx = /(cat|dog)/gi;
var m = null;
m = rx.exec(w[i]);
if(m){
document.writeln("<p>" + i + "<br/>INPUT: " + w[i] + "<br/>MATCHES: " + w[i].length + "</p>");
}else{
document.writeln("<p><b>" + i + "<br/>'" + w[i] + "' FAILED.</b><br/>" + w[i].length + "</p>");
}
document.writeln(m);
}
回答by Frode
The regex object has a property lastIndexwhich is updated when you run exec. So when you exec the regex on e.g. "I have a cat and a dog too.", lastIndexis set to 12. The next time you run execon the same regex object, it starts looking from index 12. So you have to reset the lastIndexproperty between each run.
regex 对象有一个属性lastIndex,当您运行exec. 因此,当您在例如“我也有一只猫和一只狗。”上执行正则表达式时,lastIndex设置为 12。下次您exec在同一个正则表达式对象上运行时,它从索引 12 开始查找。因此您必须重置该lastIndex属性每次运行之间。
回答by ESL
Two things:
两件事情:
- The mentioned need of resetwhen using the
g(global) flag. To solve this I recommed simply assign0to thelastIndexmember of theRegExpobject. This have better performance than destroy-and-recreate. - Be careful when use
inkeyword in order to walk anArrayobject, because can lead to unexpected results with some libs. Sometimes you should check with somethign likeisNaN(i), or if you know it don't have holes, use the classic for loop.
- 使用(全局)标志时提到的重置需要
g。为了解决这个问题,我建议简单地分配0给对象的lastIndex成员RegExp。这比销毁并重新创建具有更好的性能。 - 使用
in关键字来遍历Array对象时要小心,因为可能会导致某些库出现意外结果。有时你应该检查类似的东西isNaN(i),或者如果你知道它没有漏洞,使用经典的 for 循环。
The code can be:
代码可以是:
var rx = /(cat|dog)/gi;
w = ["I have a cat and a dog too.", "There once was a dog and a cat.", "I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat."];
for (var i in w)
if(!isNaN(i)) // Optional, check it is an element if Array could have some odd members.
{
var m = null;
m = rx.exec(w[i]); // Run
rx.lastIndex = 0; // Reset
if(m)
{
document.writeln("<pre>" + i + "\nINPUT: " + w[i] + "\nMATCHES: " + m.slice(1) + "</pre>");
} else {
document.writeln("<pre>" + i + "\n'" + w[i] + "' FAILED.</pre>");
}
}
回答by Don
I had a similar problem using /g only, and the proposed solution here did not work for me in FireFox 3.6.8. I got my script working with
我只使用 /g 时遇到了类似的问题,这里建议的解决方案在 FireFox 3.6.8 中对我不起作用。我得到了我的脚本
var myRegex = new RegExp("my string", "g");
I'm adding this in case someone else has the same problem I did with the above solution.
我添加这个以防其他人遇到与上述解决方案相同的问题。

