Question

I have a problem with Regex when used for custom validation.

I have this unobtrusive method:

jQuery.validator.addMethod("isRegex", function (value, element, params) {
    if (value.length < 1) return true;
    var re = new RegExp(params.regex);
    var match = re.exec(value);
    return match;
});

At first I was using this regular expression for validation an email form field:

^\w+([-+.]*[\w-]+)*@(\w+([-.]?\w+)){1,}\.\w{2,4}$

The event would be fired "onkeyup" and at first it would work but if the email address was too long it would cause the browser to hang and the only way to recover would be restarting the browser. This happened on IE and chrome but probably Firefox too.

So for example typing "test@test.com" would work fine. "testtesttest@ttest.com" would also work without problems but "testtesttesttesttesttest@ttest.com" would hang towards the last letters.

At first I thought maybe the regex was an inneficient one causing infinite loops or locks so I changed it to something simple:

^.+@.+\..+$

Partial success, I can type longer email addresses but it still hangs eventually.

Then I thought I should disable the onkeyup event and maybe just validate on blur and for that I used:

   $("#divEmail input[data-val-fieldregex]").keyup(function () { return false; });

Now the keyup is disabled but the browser hangs on blur, so it means the code:

    var re = new RegExp(params.regex);
    var match = re.exec(value);

Must be unable to handle large values.

Any ideas?

Was it helpful?

Solution

Try to replace ([-+.]*[\w-]+)* by ([-.]\w+)*

^\w+([-.]\w+)*@\w+([-.]\w+)*\.\w{2,4}$

You can find more informations about catastrophic backtracking here.

The second pattern can cause a catastrophic backtracking too since the dot can match the literal dot, and the arobase.

Note that this kind of pattern is very basic and will exclude many well formed email addresses.

OTHER TIPS

Try this instead...

jQuery.validator.addMethod('isRegex', function (value, element, param) {
    return this.optional(element) || param.test(value);
});

And within .validate()...

rules: {
    field: {
        isRegex: /^\w+([-+.]*[\w-]+)*@(\w+([-.]?\w+)){1,}\.\w{2,4}$/i
    }
},

Working DEMO: http://jsfiddle.net/ZdCee/


BTW, what's wrong with the email method already built into this plugin?

http://jqueryvalidation.org/email-method/

email: function( value, element ) {
    // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
    return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
},

DEMO: http://jsfiddle.net/ZdCee/1/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top