2

正規表現に問題があると思います。最初の丸かっこ内のすべての文字を含むことができる文字列が必要で、最終的には [ 、最後に ] です。正規表現は次のとおりです。

    var pattern = /^(([a-zA-Z0-9\.\_\-\(\)\\'\xE0\xE8\xE9\xF9\xF2\xEC\x27\,\/]\s?)*\[?([a-zA-Z0-9\.\_\-\(\)\\'\xE0\xE8\xE9\xF9\xF2\xEC\x27\,\/]\s?)*\]?)+$/;

問題は、次の文字列 Maionese [dfvdfv]@ をテストしようとすると、プログラムが永遠にループすることです:-|

テストに使用する関数は次のとおりです。

//the alert doesn't works
alert(checkSpecialIngredienti("Maionese [dfvdfv]@"));
function checkSpecialIngredienti(s) {

var pattern = /^(([a-zA-Z0-9\.\_\-\(\)\\'\xE0\xE8\xE9\xF9\xF2\xEC\x27\,\/]\s?)*\[?([a-zA-Z0-9\.\_\-\(\)\\'\xE0\xE8\xE9\xF9\xF2\xEC\x27\,\/]\s?)*\]?)+$/;
if (!pattern.test(s)) {
    alert("Attenzione, il campo "+s+"" +
            " che hai inserito non va bene!" +
            "\nIn questo campo puoi inserire " +
            "lettere, numeri, lettere accentate," +
            "punteggiatura classica, singoli spazi e" +
            "\nuna sola coppia di parentesi quadre." +
            "\nRiprova!");
    return (false);
} else
    return true;
}
4

1 に答える 1

2

量指定子 ( ) がネストされているため、壊滅的なバックトラッキング((...)*)+が発生しており、結果として生じる組み合わせの爆発により、対象の文字列が一致しない場合に正規表現エンジンが爆発します。

さて、これを修正する方法は?まず、正規表現を単純化しましょう。そこには多くのいらいらするクラフトがあります.次の正規表現はあなたのものとまったく同じ文字列に一致しますが、読みやすいです:

/^(([\w\s.,()\\\/'\xE0\xE8\xE9\xF9\xF2\xEC\x27-])*\[?([\w\s.,()\\\/'\xE0\xE8\xE9\xF9\xF2\xEC\x27-])*\]?)+$/

問題が明らかになりました: []s は両方ともオプションであり、@テスト文字列の は許可された文字範囲の一部ではありません。これは、 に遭遇する@と、正規表現エンジンは一致に戻って、前の部分に一致する他の方法があるかどうかを確認する必要があることを意味します。試行する必要がある方法はたくさんあります。

あなたの仕様によると、許可された文字のいずれかと最後に同じ文字の+オプションの - で囲まれた文字列を含む文字列に一致させたいと思われるため、最後の文字はまったく必要ありません。[...]その場合は、

/^([\w\s.,()\\\/'\xE0\xE8\xE9\xF9\xF2\xEC\x27-]*)(\[[\w\s.,()\\\/'\xE0\xE8\xE9\xF9\xF2\xEC\x27-]*\])?$/
于 2012-11-27T15:21:49.940 に答える