2

I think I've a problem with regular expression: I want a string wich can contains all the characthers in the first rounded parenthesis and eventually a [ and finally a ]. the regex is the following:

    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?)*\]?)+$/;

the problem is that if I try to test the following string Maionese [dfvdfv]@ my program will loop forever :-|

the function that I use to test is the following:

//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;
}
7
  • I don't see any possible way for your program to loop with this code. Commented Nov 27, 2012 at 15:00
  • I know that there is not a loop but the program stops Commented Nov 27, 2012 at 15:09
  • Please provide a short self-contained correct example that demonstrates your problem. JSFiddle is a great tool for this. Commented Nov 27, 2012 at 15:12
  • I don't know how to use this tool... I try... Commented Nov 27, 2012 at 15:18
  • doc.jsfiddle.net Commented Nov 27, 2012 at 15:20

1 Answer 1

2

You're running into catastrophic backtracking because you have nested quantifiers (((...)*)+), and the resulting combinatorial explosion will blow up your regex engine when the subject string cannot be matched.

Now, how to fix this? Let's first simplify your regex. There's a lot of irritating cruft in there - the following regex matches exactly the same strings as yours, but it's easier to read:

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

The problem now becomes clear: The []s are both optional, and the @ in your test string is not part of the allowed character range. This means that upon encountering the @, the regex engine needs to backtrack into the match and check if there is any other way to match the preceding part - and there are lots of ways that it has to try.

According to your specs, you don't need the final + at all, since you seem to be wanting to match a string that contains any of the allowed characters plus one optional, [...]-enclosed string of the same characters at the end. In that case, use

/^([\w\s.,()\\\/'\xE0\xE8\xE9\xF9\xF2\xEC\x27-]*)(\[[\w\s.,()\\\/'\xE0\xE8\xE9\xF9\xF2\xEC\x27-]*\])?$/
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.