1

我用正則表達式時用於自定義驗證有問題。JavaScript的正則表達式評估導致瀏覽器掛起

我有這個不顯眼的方法:

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。

因此,例如鍵入「[email protected]」將工作正常。 「[email protected]」也可以毫無問題地工作,但「[email protected]」會掛在最後的字母上。

起初我想,也許正則表達式是一個inneficient一個導致無限循環或鎖,所以我把它改爲簡單的東西:

^[email protected]+\..+$ 

部分成功,我可以輸入較長的電子郵件地址,但它仍然掛起最終。

然後我想我應該禁用onkeyup事件,也許只是驗證的模糊和我使用的:

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

現在KEYUP被禁止,但瀏覽器掛起模糊,所以這意味着代碼:

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

必須無法處理較大的值。

任何想法?

+0

http://www.regular-expressions.info/catastrophic.html – Bergi

回答

0

嘗試通過([-.]\w+)*

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

更換([-+.]*[\w-]+)*您可以找到有關災難性回溯here更多的信息。

第二種模式也可能導致災難性的回溯,因爲點可以匹配字面點和arobase。

請注意,這種模式是非常基本的,將排除許多格式良好的電子郵件地址。

+0

我試着用^ + @ + \ .. + $,甚至雖然問題有所改善,但仍然存在問題 – Nick

+0

你說得對。我使用^ \ w +([ - 。] \ w +)* @ \ w +([ - 。] \ w +)* \。\ w {2,4} $並重新啓動瀏覽器,它不再卡住 – Nick

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/

+0

我可以' t使用內置的,但事實證明,瀏覽器只需要重啓。 – Nick

相關問題