Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Browser tab stucks when my RegEx is executed and do not match the input

The problem is next. I created an input field which has validation and this is valid data:

  1. 1-12, 14, 16, 22, 25-35, 41, 49, 55-90
  2. 1230-1992, 2001-2099, 9931
  3. 1-2
  4. 13
  5. 1,3,4,5,6,10
  6. all

Basically, any combination of those numbers (ranges, comma-separated ranges, comma-separated number, spaces after commas, no spaces after commas, word: 'all')

My RegEx: /^(([0-9]{0,4},?\s{0,})+([0-9]{1,4}-[0-9]{1,4}){0,},?\s{0,})+$|^(all)$|^([0-9]{1,4}-[0-9]{1,4}){0,},?\s{0,}$/

It works almost fine, there is only 1 major problem.

When I start typing, and after some comma-separated numbers I add something that is not valid, like characters: 'abc' - and at this moment my browser tab stucks.

Try this as an input: 1-12, 14, 16, 19, 20-29, was

Fiddle to test: http://jsfiddle.net/c9ahfhqy/

Is there any suggestions on how the proper RegEx should look like?

Code:

    $("input[type='text']").blur(function() { //when you lose focus on input
      doneTyping();
    });

    function doneTyping() {
      if(!$('#inputToCheck').val().match(/^(([0-9]{0,4},?\s{0,})+([0-9]{1,4}\-[0-9]{1,4}){0,},?\s{0,})+$|^(all)$|^([0-9]{1,4}\-[0-9]{1,4}){0,},?\s{0,}$/)) {
        console.log("Not Valid");
      } else {
        console.log("Valid");
      }
    }

Really appreciate help.

like image 807
admix Avatar asked Aug 21 '14 18:08

admix


1 Answers

As @derp said, your regex has a problem of Catastrophic Backtracking.

The following one seems to work like you want, and doesn't freeze the browser:

/^(?:all|\d{1,4}(?:-\d{1,4})?(?:,\s*\d{1,4}(?:-\d{1,4})?)*)$/

Demo

Using RegexBuddy's debugger to test 1-12, 14, 16, 19, 20-29, was,

  • You regex fails after attempting 1000000 steps, with this error:

    Your regular expression is too complex to continue debugging.
    The regex engine you plan to use it with may not be able to handle it at all and crash.
    Look up "catastrophic backtracking" in the help file to learn how to avoid this situation.

  • The regex above fails after 96 steps, with no error.

like image 177
Oriol Avatar answered Sep 27 '22 20:09

Oriol