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 都是可选的,并且@您的测试字符串中的 s 不是允许的字符范围的一部分。这意味着在遇到 时@,正则表达式引擎需要回溯到匹配中并检查是否有任何其他方法可以匹配前面的部分 - 而且它必须尝试很多方法。

根据您的规范,您根本不需要 final +,因为您似乎想要匹配一个字符串,该字符串包含任何允许的字符加上一个可选[...]的 - 结尾的相同字符的封闭字符串。在这种情况下,使用

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