2010-05-06 213 views
4

是這個JavaScript函數(checkValidity)正確嗎?電子郵件驗證javascript

function checkTextBox(textBox) 
{ 
    if (!checkValidity(textBox.getValue())) 
     displayError("Error title", "Error message", textBox); 
     textBox.focus(); 
} 

function checkValidity(e) 
{ 
    var email; 
    email = "/^[^@][email protected][^@]+.[a-z]{2,}$/i"; 

    if (!e.match(email)){ 
      return false; 
    else 
      return true; 
    } 
} 

編輯:所有的答案感謝!謝謝!

+2

基本上,這個問題的答案應該學習你兩件事情: 1)許多人不以爲然如何實現它 2)的解決方案,似乎什麼東西無處不異常複雜.. 。這可能意味着電子郵件地址的規範已被破壞:) – 2010-05-06 20:34:45

回答

7

電子郵件地址在RFC 5322, § 3.4中定義。相關的非終端是addr-spec。由於領域規範的複雜性和支持陳舊,過時的形式,這個定義變得有些詭異。但是,您可以對大多數表單進行過度逼近:

^[-0-9A-Za-z!#$%&'*+/=?^_`{|}~.][email protected][-0-9A-Za-z!#$%&'*+/=?^_`{|}~.]+ 

請注意,存在大量的合法字符。大多數reg-exs都會列出錯誤。是的,所有這些字符在電子郵件地址中都是合法的。

這個正則表達式不匹配一些非常罕見的使用形式,如"noodle soup @ 9"@[what the.example.com] - 這是一個合法的電子郵件地址!

+0

這種形式似乎工作正常,但它不需要頂級域名。允許名稱@電子郵件沒有任何.com或其他。我需要添加什麼來解決這個問題? – 2013-01-04 19:14:13

+1

也許你想確保至少有一個點?將'\。[ - 0-9A-Za-z!#$%&'* +/=?^ _'{|}〜。] +'加到最後!如果你想忽略國際化的頂級域名,你可以簡化爲只添加'\。[A-Za-z] +' – MtnViewMark 2013-01-06 07:15:39

+0

我在**點上獲得了Visual Studio 2012中'無法識別的轉義序列' **之後** '[RegularExpression(「^ [ - 0-9A-Za-z!#$%&'* +/=?^ _ {|}〜。] + @ [ - 0-9A-Za- !ž#$%& '* +/=^_ {|}〜] \ [ - 0-9A-ZA-Z#$%&?!' * +/=^_?{|}〜] {2,4} +「,ErrorMessage =」無效的電子郵件「)]' 任何想法爲什麼會發生? – 2013-01-07 15:42:50

1

不。它假定電子郵件地址只能包含一個@。我建議閱讀this article

您可能也意味着\.而不是.

+0

地址不能包含多個@,除非他們使用的是過時的表單。 – 2010-05-06 19:40:49

+1

@Thom不對。閱讀RFC。 – 2010-05-06 19:42:39

+2

實際上,RFC允許@在帶引號的字符串內部,它可以在將本地部分與域分開的@之前。所以"[email protected]"@example.com是一個有效的電子郵件地址。 – MtnViewMark 2010-05-06 23:13:56

1

試試這個:我確定它需要處理各種電子郵件驗證。

function checkEmail(email) 
{ 
    if(/^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(email)) { 
     return true; 
    } else { 
     return false; 
    } 
} 

HTH

+0

我認爲你可以放心地忽略幾十年來一直沒有使用過的某些棄用格式的地址。 – 2010-05-06 19:12:13

+0

RFC 5322§3.4.1定義了電子郵件的地址規範。它不允許這裏列出的字符範圍。具體而言,它不支持非ASCII字符。 – MtnViewMark 2010-05-06 19:16:25

2

不,這正則表達式是不是適合這個目的。而不是(但我不能保證它的有效性)。
此外,關於腳本本身,你爲什麼不檢查是這樣的:

function checkEmailValidity(e) { 
    return e.match("some validating regex"); 
} 

這似乎是一個更快,更consise和更具可讀性的解決方案。

編輯:
值得一提的,這幾乎是不可能的編寫一個正則表達式,可以檢測到任何有效的電子郵件地址。因此,您可能會更好地嘗試製作一些驗證算法,而不是正則表達式,因爲有效的電子郵件地址可能非常非常複雜。

考慮以下代碼:

function validateEmail(email) { 
    if (typeof email != "string") return false; 
    email = email.split("@"); 
    email[1] = email[1].split("."); 
    if (
     email.length !== 2 || 
     email[1].length < 2 || 
     !email[1].hasValues(String) 
    ) return false; 
    return true; 
} 

// Checks whether each key in an array has a value, and (optionally) if they match a given contructor (object type). 
// I.e.: myArray.hasValues(String) // checks whether all elements in myArray has a value, a nonempty string. 
Array.prototype.hasValues = function(assumedConstructor) { 
    for (var i = 0; i < this.length; i++) { 
     if (!this[i]) return false; 
     if (assumedConstructor && this[i].constructor != assumedConstructor) return false; 
    } 
    return true; 
}; 

它的工作原理是這樣的:

  1. 首先檢查是否字符串包含一個@,且只有一個
  2. 檢查該@後的部分在至少有一個.
  3. 檢查每個可能的之間是否有一些字符10歲。

它仍然會很容易僞造一個假的電子郵件地址,但這樣一來,我們確保它至少莫名其妙格式正確。我能想到的唯一問題是@的內部註釋,根據RFC的說法,這應該是完全合法的,但是這段代碼將它視爲錯誤。
正常的互聯網用戶,其中有正常的電子郵件地址,不會失敗。所以它的實際重要性取決於你自己決定;)

最好的解決方案,如果有的話,就是把地址放入一些內置的方法,以某種方式通過嘗試使用電子郵件來檢查有效性地址。

+1

在引用的文章中的正則表達式是錯誤的 - 作者只是聲稱他的電子郵件地址的定義是好的 - 只有它是由RFC定義的,他是錯誤的。 – MtnViewMark 2010-05-06 19:12:20

+0

我很抱歉參考。我通常不會做正則表達式,所以我不知道。 – 2010-05-06 19:16:12

3
function isValidEmail($email) 
{ 
    return eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$", $email); 
}; 

if(isValidEmail("[email protected]")) 
{ 
    echo "valid"; 
} 
else 
{ 
    echo "aaa"; 
}; 
+0

誰想過在函數聲明和if語句之後放置';'? – 2013-02-22 06:38:08

1

這是一個對應於RFC的正則表達式,不包括過時的表單。我打破它分成組件,以便它會很容易閱讀:

IDENT = [a-z0-9](?:[a-z0-9-]*[a-z0-9])? 
TEXT = [a-z0-9!#$%&'*+/=?^_`{|}~-]+ 

EMAIL = TEXT(?:\.TEXT)*@IDENT(?:\.IDENT)+ 

(注:不區分大小寫)

這將不匹配,之前使用引號形式的電子郵件地址@或者是後面的括號形式,但是這些形式是有效的,但它們現在在例子之外幾乎沒有見過,它們使正則表達式顯着複雜化。

1

驗證電子郵件地址是非常困難。除了非常基本的檢查@.字符之外,它甚至不值得在客戶端進行驗證。

Section 3.4.1 of RFC 5322闡述了各種各樣的法律角色,你會發現創建一個防彈正則表達式幾乎是不可能的。

我最終放棄了驗證,因爲我偶爾會收到用戶的投訴,說他們的瘋狂電子郵件地址不起作用。所以,從現在起,我只是試圖發送電子郵件,並希望它能夠交付。如果發送失敗,那麼我告訴用戶他們的電子郵件地址有問題。