【问题标题】:javascript regex evaluation causes browser to hangjavascript 正则表达式评估导致浏览器挂起
【发布时间】:2013-12-09 12:39:09
【问题描述】:

我在使用 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; });

现在keyup被禁用但浏览器挂在模糊上,所以这意味着代码:

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

必须无法处理大值。

有什么想法吗?

【问题讨论】:

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


【解决方案1】:

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

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

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

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

请注意,这种模式非常基本,会排除许多格式正确的电子邮件地址。

【讨论】:

  • 我用 ^.+@.+\..+$ 试过了,虽然问题有所改善,但还是有问题
  • 你是对的。我用 ^\w+([-.]\w+)*@\w+([-.]\w+)*\.\w{2,4}$ 并重新启动浏览器,它不再卡住了
【解决方案2】:

试试这个吧……

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

演示:http://jsfiddle.net/ZdCee/1/

【讨论】:

  • 我不能使用内置的,但事实证明浏览器只需要重新启动。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
  • 1970-01-01
  • 2015-06-26
相关资源
最近更新 更多