5

アプリの問題をデバッグしようとしていますが、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));

問題を回避するために正規表現を記述するより良い方法があるでしょうか? 目標は、正規表現がコンマまたはセミコロンで区切られた数字の文字列をキャッチすることです。

4

2 に答える 2

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

オプションの要素を含む繰り返しグループを含み、そのうちの 1 つが繰り返されます。今のところセパレーターを無視すると、本質的に正規表現があります

^(\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
于 2013-08-01T15:47:47.110 に答える
4

このパターンはよりうまく機能します:

var rgx = /^\d+(?:[,;]\s*\d+)*$/;
于 2013-08-01T15:48:22.953 に答える