我正在尝试调试我的应用中的问题,我已经缩小到涉及正常表达式的特定情况,导致Chrome窒息!在Firefox中尝试相同的代码可以正常工作。如果我减少我的样本'运行正则表达式的文本也可以。
那是什么给了什么?
以下是jsfiddle:http://jsfiddle.net/XWKRb/1/ (这将无法初始化,因为如果你得到与我相同的结果,Chrome会窒息)
我在jsfiddle中输入的代码是:
var rgx = /^(\d+([,|;]?\d*))*$/;
var sample = '40162690,40162755,40162691,40168355,40168357,40162726,40162752,40162729,40428707 ,40162740,40162546';
alert("Test is "+rgx.test(sample));
也许有更好的方法来编写我的正则表达式来避免这个问题?目标是正则表达式应该捕获一串用逗号或分号分隔的数字。
答案 0 :(得分:13)
您有catastrophic backtracking的经典案例:
^(\d+([,|;]?\d*))*$
^ ^ ^ ^
| | | ---- zero or more repetitions of the group
| | ------- zero or more digits
| ---------- zero or one comma, pipe or semicolon
----------------- one or more digits
包含一个包含可选元素的重复组,其中一个元素会自行重复。暂时忽略分隔符,你基本上有正则表达式
^(\d+\d*)*$
这导致你的正则表达式在最坏的情况下必须检查的指数数量的排列。
只要在你的字符串中找到了允许字符之外的另一个字符(就像你的例子中的空格一样),正则表达式必须失败 - 但需要引擎年龄来计算出来。有些浏览器会检测到这种失控的正则表达式匹配,但Chrome似乎想要解决此问题。
为了说明这一点,在RegexBuddy中测试正则表达式会显示以下内容:
Input Steps to determine a non-match
1,1X 23
12,21X 119
123,321X 723
1234,4321X 4,743
12345,54321X 31,991
123456,654321X 217,995
1234567,7654321X attempt aborted after 1,000,000 steps
答案 1 :(得分:4)
这种模式会更好用:
var rgx = /^\d+(?:[,;]\s*\d+)*$/;