javascript正则表达式评估会导致浏览器挂起

时间:2013-12-09 12:39:09

标签: regex asp.net-mvc-4 jquery-validate unobtrusive-validation

用于自定义验证时,我遇到了Regex的问题。

我有这种不引人注意的方法:

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;
});

起初我使用这个正则表达式验证电子邮件表单字段:

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

该事件将被触发“onkeyup”,并且最初它会起作用,但如果电子邮件地址太长则会导致浏览器挂起,恢复的唯一方法就是重新启动浏览器。这发生在IE和Chrome上,但也可能是Firefox。

因此,例如输入“test@test.com”可以正常工作。 “testtesttest@ttest.com”也可以顺利运行,但“testtesttesttesttesttest@ttest.com”会挂在最后的字母上。

起初我想也许正则表达式是一个无效的导致无限循环或锁定所以我把它改成了简单的东西:

^.+@.+\..+$

部分成功,我可以输入更长的电子邮件地址但最终仍会挂起。

然后我想我应该禁用onkeyup事件,也许只是验证模糊和我使用过:

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

现在键盘已禁用,但浏览器因模糊而挂起,因此它代表代码:

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

必须无法处理大值。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

尝试将([-+.]*[\w-]+)*替换为([-.]\w+)*

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

您可以找到有关灾难性回溯here的更多信息。

第二种模式也可能导致灾难性的回溯,因为点可以匹配字面点和arobase。

请注意,此类模式非常基本,并且会排除许多格式良好的电子邮件地址。

答案 1 :(得分:0)

试试这个......

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

.validate() ......

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

工作演示:http://jsfiddle.net/ZdCee/


顺便说一下,这个插件中已经内置的email方法出了什么问题?

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/