本文範例使用正則表達式來驗證字串是否為有效的電子郵件格式。
這個正則表達式比實際可用作電子郵件的表達方式簡單許多。 使用正則表達式來驗證電子郵件有助於確保郵件結構正確。 然而,這並不等於驗證該電子郵件是否真實存在。
✔️ 請使用小型正則表達式來檢查電子郵件的有效結構。
✔️ 請務必寄送測試郵件到你應用程式使用者提供的地址。
❌ 千萬不要只用正規表達式來驗證郵件。
如果你試圖創造 完美的 正則表達式來驗證電子郵件結構是否正確,這個表達式會變得非常複雜,難以除錯或改進。 正規表達式無法驗證電子郵件的存在,即使郵件結構正確。 驗證電子郵件的最佳方法是寄出測試郵件到該地址。
Warning
若在不受信任的輸入下不受限制地使用, System.Text.RegularExpressions 應用程式可能會遭受 阻斷服務攻擊。 請參閱 .NET 中正則表達式的最佳實務,以獲得如何在不受信任輸入下安全使用 .NET 正規表達式的指引。
Example
範例定義了一個IsValidEmail方法,若字串包含有效電子郵件地址true則回傳false;若無則不執行其他動作。
為了驗證電子郵件地址的有效性,該 IsValidEmail 方法會以正則表達式模式呼叫該 Regex.Replace(String, String, MatchEvaluator) 方法 (@)(.+)$ ,將網域名稱與電子郵件地址分離。 第三個參數是一個 MatchEvaluator 代理,代表處理並替換匹配文本的方法。 正則表達式模式的解釋如下:
| 樣式 | Description |
|---|---|
(@) |
匹配 @ 字元。 這個部分是第一個擷取群組。 |
(.+) |
匹配任何角色的一個或多個事件。 這個部分是第二個擷取群組。 |
$ |
在字串的結尾結束比對。 |
網域名稱連同 @ 字元會傳遞給 DomainMapper 方法。 此方法利用 類別 IdnMapping 將超出 US-ASCII 字元範圍的 Unicode 字元轉換為 Punycode。 如果IdnMapping.GetAscii方法偵測到網域名稱中有任何無效字元,該方法也會將invalid旗標設為True。 此方法會將前面加上 @ 符號的 Punycode 網域名稱回傳給 IsValidEmail 方法。
秘訣
建議你使用簡單的 (@)(.+)$ 正則表達式模式來正規化領域,然後回傳一個值表示通過或失敗。 不過,本文的範例說明了如何進一步使用正則表達式來驗證電子郵件。 無論你如何驗證電子郵件,都應該先寄出測試郵件到該地址,以確保郵件存在。
接著,該 IsValidEmail 方法呼叫該 Regex.IsMatch(String, String) 方法來驗證地址是否符合正則表達式模式。
此 IsValidEmail 方法僅判斷該電子郵件格式是否適用於該電子郵件地址;並不會驗證該電子郵件的存在。 此外,這個 IsValidEmail 方法無法驗證頂層網域名稱是否為 IANA 根區資料庫中的有效網域名稱,這需要進行查詢操作。
using System;
using System.Globalization;
using System.Text.RegularExpressions;
namespace RegexExamples
{
class RegexUtilities
{
public static bool IsValidEmail(string email)
{
if (string.IsNullOrWhiteSpace(email))
return false;
try
{
// Normalize the domain
email = Regex.Replace(email, @"(@)(.+)$", DomainMapper,
RegexOptions.None, TimeSpan.FromMilliseconds(200));
// Examines the domain part of the email and normalizes it.
string DomainMapper(Match match)
{
// Use IdnMapping class to convert Unicode domain names.
var idn = new IdnMapping();
// Pull out and process domain name (throws ArgumentException on invalid)
string domainName = idn.GetAscii(match.Groups[2].Value);
return match.Groups[1].Value + domainName;
}
}
catch (RegexMatchTimeoutException e)
{
return false;
}
catch (ArgumentException e)
{
return false;
}
try
{
return Regex.IsMatch(email,
@"^[^@\s]+@[^@\s]+\.[^@\s]+$",
RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
}
catch (RegexMatchTimeoutException)
{
return false;
}
}
}
}
Imports System.Globalization
Imports System.Text.RegularExpressions
Public Class RegexUtilities
Public Shared Function IsValidEmail(email As String) As Boolean
If String.IsNullOrWhiteSpace(email) Then Return False
' Use IdnMapping class to convert Unicode domain names.
Try
'Examines the domain part of the email and normalizes it.
Dim DomainMapper =
Function(match As Match) As String
'Use IdnMapping class to convert Unicode domain names.
Dim idn = New IdnMapping
'Pull out and process domain name (throws ArgumentException on invalid)
Dim domainName As String = idn.GetAscii(match.Groups(2).Value)
Return match.Groups(1).Value & domainName
End Function
'Normalize the domain
email = Regex.Replace(email, "(@)(.+)$", DomainMapper,
RegexOptions.None, TimeSpan.FromMilliseconds(200))
Catch e As RegexMatchTimeoutException
Return False
Catch e As ArgumentException
Return False
End Try
Try
Return Regex.IsMatch(email,
"^[^@\s]+@[^@\s]+\.[^@\s]+$",
RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250))
Catch e As RegexMatchTimeoutException
Return False
End Try
End Function
End Class
在此範例中,正則表達式模式 ^[^@\s]+@[^@\s]+\.[^@\s]+$ 的解釋方式如下表所示。 正規表達式是使用 旗 RegexOptions.IgnoreCase 標編譯的。
| 樣式 | Description |
|---|---|
^ |
從字串的起始處開始匹配。 |
[^@\s]+ |
匹配一個或多個非 @ 字元或空白字元的出現。 |
@ |
匹配 @ 字元。 |
[^@\s]+ |
比對一個或多個非 @ 或空白的任意字元。 |
\. |
匹配單一時期的角色。 |
[^@\s]+ |
匹配一個或多個非 @ 字元或空白字元的出現。 |
$ |
在字串的結尾結束比對。 |
Important
這個正則表達式並非旨在涵蓋有效電子郵件地址的所有面向。 這是作為範例,供你根據需要延伸。