JavaScript >> Javascript 文檔 >  >> Tags >> Date

在 JavaScript 中使用正則表達式驗證電子郵件地址

簡介

對於 Web 開發人員來說,驗證各種形式的用戶輸入至關重要。由於這是在客戶端和服務器之間發送數據的起點,因此您需要確保一切都以正確的方式開始 - 以免您最終在 服務器 上得到可靠的驗證 end,這通常比在前端做更麻煩。

此外,輸入可能是惡意的——在這種情況下,您還必須考慮安全性。最好通過在前端驗證輸入來完全避免它。

JavaScript 中的正則表達式

對於不熟悉正則表達式的任何人,或者任何覺得他們需要快速提醒的人,這裡就是!

通過元字符、量詞、組和轉義字符——你可以表達 幾乎任何模式。例如,這個表達式表示一個字符序列,其中包含 A-Z(小寫和大寫)之間的任何有效字母 數字,任意組合:

^([A-Za-z]|[0-9])+$

這也稱為檢查序列是否為字母數字 .

對於本指南的其餘部分,我們將假設您對正則表達式有所了解。

用正則表達式匹配 JavaScript 中的電子郵件格式

首先,匹配所有可能的有效電子郵件地址的正則表達式不存在 .但是,匹配 99.9% 的那個 , 做。在驗證電子郵件或任何輸入時,一個可以或多或少保證用戶匹配正則表達式的好做法是預先限制用戶輸入。

例如,強制使用 gmail.comyahoo.com 並直接拒絕不受支持的提供程序(不過,您確實會遇到可擴展性問題並與此方法保持同步)。

又提出一個問題:

正如我們很快就會看到的,這是一個令人驚訝的鬆散定義——你可以在這方面變得簡單或健壯。我們將介紹用於驗證電子郵件的最通用的正則表達式,以及指南中更具體的那些。

在我們進入代碼之前,讓我們預覽一下我們將要研究的電子郵件格式:

  • 一般格式 - (something)@(some_domain).(some_toplevel_domain)
  • 特定主機或域 - 指特定類型的域或頂級域
  • RFC 5322 - 互聯網消息格式,覆蓋 99.9% 的電子郵件地址

通用電子郵件格式正則表達式

在多次嘗試使用健壯的正則表達式進行驗證之後,許多工程師退回到大部分時間都可以使用的老式“通用”格式。這是否是一件好事是可以討論的。

電子郵件地址意味著什麼?它必須有一個 @ 符號,以及一些 前面的字符串,以及 some 字符串繼續它。另外,第二個字符串需要包含一個點,點後面還有2-3個字符。

總之,這是一個粗略的草圖:

(randomString)@(randomString2).(2-3 characters)

這遵循這些電子郵件有效的一般直覺:

[email protected]
[email protected]
[email protected]

考慮到這一點,為了通過正則表達式在 JavaScript 中驗證電子郵件地址,我們將粗略的草圖翻譯成 RegExp

let regex = new RegExp('[a-z0-9][email protected][a-z]+\.[a-z]{2,3}');

let testEmails = ["notanemail.com", "[email protected]", "[email protected]", "[email protected]"];

testEmails.forEach((address) => {
    console.log(regex.test(address))
});

第一個字符串可以包含任何小寫字母數字字符 - john.doe.1 , workingemail 等。

這導致:

false
true
true
false

這會一直有效嗎?不會。會有一些 傳遞的格式錯誤的電子郵件。您也無法使用此正則表達式執行垃圾郵件檢測,因此直觀上看起來像垃圾郵件的電子郵件地址可以很好地通過此表達式:

console.log(regex.test("[email protected]")); // true

免費電子書:Git Essentials

查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!

雖然,即使是最強大、最複雜的電子郵件地址驗證表達式也無法解決這個問題——它們是用來驗證 form ,而不是電子郵件是否存在。

特定電子郵件地址

降低不確定性會有所幫助。不確定性越少,限制就越少 需要使用表達式強加。這使得使用我們剛剛看到的相同通用格式的特定電子郵件地址驗證更加準確 - 您不必涵蓋盡可能多的邊緣情況。

下面我們來看看域和頂級域的一些一般情況。

使用 JavaScript 驗證電子郵件地址域

假設您在一家名為 Stack Abuse 的公司工作 .所有員工都有一封以 @stackabuse.com 結尾的電子郵件 並且用戶字符串是變化的。粗略的草圖如下所示:

(randomString)@stackabuse.com

這使我們的任務變得更加容易,因為域名和組織類型等一些變量現在已修復。這兩個是導致問題的典型變量,因為域名可能會千變萬化 .

因此,使用 RegExp 驗證屬於特定域的電子郵件地址變得很容易 類:

let regex = new RegExp('[a-z0-9][email protected]');

let testEmails = ["notanemail.com", "[email protected]", "[email protected]"];

testEmails.forEach((address) => {
    console.log(regex.test(address))
});

這導致:

false
true
false

使用這種方法,您可以根據需要更改任何文字字符串以匹配它。與往常一樣,正則表達式的第一部分可以更改為匹配大寫字母的大小寫,包括特殊字符,例如 +_ 等。

在 JavaScript 中驗證電子郵件地址頂級域

這種情況與前一種情況非常相似,只是我們將限制電子郵件的最後兩個或三個字符。
這些可以是以下任何一種:.com、.org、.edu、.歐盟,.us 等。讓我們只匹配包含 .edu 的電子郵件 因為它絕不僅僅是這個頂級域,而是類似 [email protected] .

let regex = new RegExp('[a-z0-9][email protected][a-z]+\.edu\.[a-z]{2,3}');

let testEmails = ["notanemail.com", "[email protected]", "[email protected]"];

testEmails.forEach((address) => {
    console.log(regex.test(address))
});

一封無效的電子郵件以及一封有效的電子郵件都失敗了 - 因為它們不包含 edu 但是,在他們的頂級域中,虛構的耶魯地址有效:

false
false
true

RFC 5322 格式

RFC 5322 格式 是一種 Internet 消息格式(電子郵件消息的經典格式)。 RFC 5322 只規定了應該允許的內容——它本身並不是一個表達式。

實現了多個表達式 制定的規則,這些可能會變得非常複雜。

一個簡寫版本是:

let regex = new RegExp("([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\"\(\[\]!#-[^-~ \t]|(\\[\t -~]))+\")@([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])");

而涵蓋其他邊緣情況的擴展版本是:

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

除非您將它們分成幾組並花一些時間閱讀它們,否則這些表達並不是特別容易理解。不過,更簡單的方法是將其可視化:

*圖片和準確性聲明由 EmailRegex.com 提供 .

話雖如此,讓我們改用這個表達式來驗證幾個地址:

let regex = new RegExp("([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\"\(\[\]!#-[^-~ \t]|(\\[\t -~]))+\")@([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])");

let testEmails = ["notanemail.com", "[email protected]", "[email protected]"];

testEmails.forEach((address) => {
    console.log(regex.test(address))
});

這導致:

false
true
true

您可以通過 regex101 的漂亮界面以交互方式繼續測試此表達式。

結論

總之,實際上沒有一種“正確”的方法可以使用正則表達式驗證電子郵件地址。但是,有一個錯誤的方法 - 如果您不涵蓋不應該正確的情況。

對於那些想要確保字面上幾乎所有東西的人 已涵蓋 - 使用 RFC 5322 格式。


Tutorial JavaScript 教程
  1. 角。從哪兒開始?

  2. JavaScript 101-#9 – 數組 Pt1

  3. 帶有 JavaScript typeof 運算符的自動設置面板

  4. 我自己與 react、graphql 和 postgresql 的實時聊天 [第 3 部分-Graphql 模式]

  5. 將域附加到彈性負載均衡器 (ELB)

  6. onChange 什麼時候和 onChange 不一樣?

  7. 4 個 JavaScript 項目可快速構建並在 1 個月內獲得聘用

  1. TypeScript 和 Socket.io

  2. 理解 JAVASCRIPT 閉包的簡單指南

  3. 2021 年您可以嘗試的 10 大 Angular Material 主題

  4. 如何對錯誤邊界進行 Jest 測試

  5. 用 hooks 替換 redux HOC

  6. 課程回顧:Web 開發人員訓練營

  7. 人們怎麼沒有意識到開發人員是有創造力的?!請允許我演示。

  1. 從頭開始構建用 Node.js 編寫的數據庫

  2. 使用 serviceworker 進行離線緩存

  3. 為 Payload CMS 構建自定義字段顏色選擇器 React 組件

  4. For Vs While – JavaScript 系列 – 第 15 部分