RegExp.exec()零星地返回NULL

我真的很为此疯狂,而且我已经花了不less的时间来试图弄清楚这里发生了什么。 所以请给我一个手=)

我需要在JavaScript中对string进行一些RegExp匹配。 不幸的是,它performance得非常奇怪。 此代码:

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>"); } } 

返回前两个元素的“cat”和“dog”,因为它应该是这样,但是一些exec() calls开始返回null 。 我不明白为什么。

我在这里发布了一个小提琴,在那里你可以运行和编辑代码。

到目前为止,我已经在Chrome和Firefox中尝试了这一点。

干杯!

/克里斯托弗

哦,这是。 因为你正在定义你的正则expression式全局,它匹配第一cat ,并在循环dog的第二遍。 所以,基本上你只需要重置你的正则expression式(它是内部指针)。 参看 这个:

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

正则expression式对象有一个属性lastIndex ,它在运行exec时被更新。 所以当你执行正则expression式的时候,例如“我有一只猫和一只狗”, lastIndex被设置为12.当你下一次在同一个正则expression式对象上运行exec ,它会从索引12开始查找。所以你必须重置每次运行之间的lastIndex属性。

两件事情:

  1. 使用g (全局)标志时提到的需要复位 。 为了解决这个问题,我build议只需将0赋值给RegExp对象的lastIndex成员。 这比摧毁和重build具有更好的性能。
  2. in关键字中使用时要小心,以便走一个Array对象,因为可能会导致一些库的意外的结果。 有时你应该像isNaN(i)那样检查一下,或者如果你知道它没有漏洞,可以使用经典的for循环。

代码可以是:

 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>"); } } 

我有一个类似的问题,只使用/ g,这里提出的解决scheme在FireFox 3.6.8中并不适用于我。 我得到了我的脚本

 var myRegex = new RegExp("my string", "g"); 

我添加了这个以防其他人遇到与上述解决scheme相同的问题。