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
属性。
两件事情:
- 使用
g
(全局)标志时提到的需要复位 。 为了解决这个问题,我build议只需将0
赋值给RegExp
对象的lastIndex
成员。 这比摧毁和重build具有更好的性能。 -
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相同的问题。