문제

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?

도움이 되었습니까?

해결책

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.

다른 팁

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/

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top