匹配電子郵件地址

匹配字串中的電子郵件地址是一項艱鉅的任務,因為定義它的規範 RFC2822 很複雜,因此很難將其作為正規表示式實現。有關為什麼將電子郵件與正規表示式匹配不是一個好主意,請在不使用正規表示式時參考反模式示例 :匹配電子郵件 。從該頁面中注意的最佳建議是使用你喜歡的語言的同行評審和廣泛的庫來實現這一點。

驗證電子郵件地址格式

當你需要快速驗證條目以確保它看起來像電子郵件時,最好的選擇是保持簡單:

^\S{1,}@\S{2,}\.\S{2,}$

該正規表示式將檢查郵件地址是否為非空格分隔的長度大於 1 的字元序列,後跟 @,後跟兩個由 . 分隔的長度為 2 或更多的非空格字元序列。它並不完美,可能會驗證無效地址(根據格式),但最重要的是,它不會使有效地址無效。

檢查地址是否存在

檢查電子郵件是否有效的唯一可靠方法是檢查其是否存在。曾經有過為此目的設計的 VRFY SMTP 命令,但遺憾的是,在被垃圾郵件傳送者濫用之後,它現在不再可用了

因此,你唯一能夠檢查郵件是否有效且存在的方法是實際向該地址傳送電子郵件。

巨大的正規表示式替代品

但是,使用正規表示式驗證地址電子郵件並非不可能。唯一的問題是,這些正規表示式越接近規範,它們將越大,因此它們難以閱讀和維護。下面,你將找到在某些庫中使用的更準確的正規表示式的示例。

⚠️ 以下正規表示式用於文件和學習目的,將程式碼貼上到程式碼中是一個壞主意。相反,直接使用該庫,因此你可以依賴上游程式碼和對等開發人員來保持你的電子郵件解析程式碼的最新和維護。

Perl 地址匹配模組

這種正規表示式的最好例子是某些語言的標準庫。例如,Perl 庫中的 RFC::RFC822::Address 模組中有一個根據 RFC 嘗試儘可能準確。為了你的好奇心,你可以在這個 URL 上找到一個由該語法生成​​的正規表示式的版本,如果你想複製貼上它,這裡引用來自正規表示式的作者:

我沒有維護正規表示式[連結]。可能存在已經在 Perl 模組中修復的錯誤。

.Net 地址匹配模組

另一個較短的變體是 EmailAddressAttribute 模組中 .Net 標準庫使用的變體 :

^((([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])))\.?$

但即使它*更短,*它仍然太大而不易讀,易於維護。

Ruby 地址匹配模組

在 ruby 中, rfc822 模組中使用正規表示式的組合來匹配地址。這是一個很好的想法,因為在發現錯誤的情況下,更容易確定正規表示式部分以更改和修復它。

Python 地址匹配模組

作為一個反例,python 電子郵件解析模組不使用正規表示式,而是使用解析器實現它。