我认为我的正则表达式存在问题: 我想要一个字符串,它可以包含第一个圆括号中的所有字符,最后是[最后一个]。 正则表达式如下:
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;
}
答案 0 :(得分:2)
你遇到了catastrophic backtracking,因为你有嵌套的量词(((...)*)+
),当主题字符串无法匹配时,由此产生的组合爆炸会炸毁你的正则表达式引擎。
现在,如何解决这个问题?让我们首先简化你的正则表达式。那里有很多令人恼火的瑕疵 - 以下正则表达式与你的字符串完全匹配,但它更容易阅读:
/^(([\w\s.,()\\\/'\xE0\xE8\xE9\xF9\xF2\xEC\x27-])*\[?([\w\s.,()\\\/'\xE0\xE8\xE9\xF9\xF2\xEC\x27-])*\]?)+$/
问题现在变得清晰:[]
都是可选的,并且测试字符串中的@
不是允许的字符范围的一部分。这意味着在遇到@
时,正则表达式引擎需要回溯到匹配中并检查是否有任何其他方法来匹配前一部分 - 并且有很多方法需要尝试。
根据您的规范,您根本不需要最终+
,因为您似乎想要匹配包含任何允许字符的字符串加上一个可选字符[...]
- 最后包含相同字符的字符串。在这种情况下,请使用
/^([\w\s.,()\\\/'\xE0\xE8\xE9\xF9\xF2\xEC\x27-]*)(\[[\w\s.,()\\\/'\xE0\xE8\xE9\xF9\xF2\xEC\x27-]*\])?$/