为什么此代码会导致Chrome窒息?

Tra*_*ant 5 javascript regex google-chrome

我正在尝试调试我的应用程序中的问题,我已经缩小到涉及正则表达式的特定情况,导致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));
Run Code Online (Sandbox Code Playgroud)

也许有更好的方法来编写我的正则表达式来避免这个问题?目标是正则表达式应该捕获由逗号或分号分隔的一串数字.

Tim*_*ker 13

你有一个典型的灾难性回溯案例:

^(\d+([,|;]?\d*))*$
    ^      ^  ^  ^
    |      |  |  ---- zero or more repetitions of the group 
    |      |  ------- zero or more digits
    |      ---------- zero or one comma, pipe or semicolon
    ----------------- one or more digits
Run Code Online (Sandbox Code Playgroud)

包含一个包含可选元素的重复组,其中一个元素会自行重复.暂时忽略分隔符,你基本上有正则表达式

^(\d+\d*)*$
Run Code Online (Sandbox Code Playgroud)

这导致你的正则表达式在最坏的情况下必须检查的指数数量的排列.

只要在你的字符串中找到了允许字符之外的另一个字符(就像你的例子中的空格一样),正则表达式必定会失败 - 但需要引擎年龄来计算出来.有些浏览器检测到这种失控的正则表达式匹配,但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
Run Code Online (Sandbox Code Playgroud)