如何確認字串是否為有效的電子郵件格式
本文中的範例會使用規則運算式來確認字串是否為有效的電子郵件格式。
與實際可做為電子郵件使用的內容相較之下,這個規則運算式相當簡單。 使用規則運算式來驗證電子郵件很有用,可確保電子郵件的結構正確無誤。 不過,這並非驗證電子郵件是否實際存在的替代方式。
✔️ 請使用小型規則運算式來檢查電子郵件的有效結構。
✔️ 請傳送測試電子郵件給應用程式使用者所提供的地址。
❌ 請勿使用規則運算式做為驗證電子郵件的唯一方式。
如果您嘗試建立「完美的」規則運算式來驗證電子郵件的結構是否正確,運算式就會變得很複雜,因此非常難以偵錯或改善。 規則運算式無法驗證電子郵件存在,即使其結構正確也一樣。 驗證電子郵件的最佳方式是將測試電子郵件傳送至地址。
警告
使用 System.Text.RegularExpressions 來處理不受信任的輸入時,請傳遞逾時。 惡意使用者可以提供輸入給 RegularExpressions
,導致拒絕服務的攻擊。 使用 RegularExpressions
的 ASP.NET Core 架構 API 會傳遞逾時。
範例
此範例會定義 IsValidEmail
方法,如果字串包含有效的電子郵件地址,則這個方法會傳回 true
,否則會傳回 false
,但不會採取其他任何動作。
為了驗證電子郵件地址是否有效, IsValidEmail
方法會以 Regex.Replace(String, String, MatchEvaluator) 規則運算式模式呼叫 (@)(.+)$
方法,從電子郵件地址分離出網域名稱。 第三個參數是 MatchEvaluator 委派,用於表示處理並取代相符文字的方法。 規則運算式模式解譯如下:
模式 | 描述 |
---|---|
(@) |
比對 @ 字元。 這個部分是第一個擷取群組。 |
(.+) |
比對出現一次或多次的任何字元。 這個部分是第二個擷取群組。 |
$ |
在字串的結尾結束比對。 |
網域名稱會連同 @ 字元一併傳遞至 DomainMapper
方法。 該方法會使用 IdnMapping 類別將 US-ASCII 字元範圍以外的 Unicode 字元轉譯為 Punycode。 如果 invalid
方法在網域名稱中偵測到任何無效字元,則方法也會將 True
旗標設定為 IdnMapping.GetAscii 。 方法會將前面加上 @ 符號的 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 旗標所編譯。
模式 | 描述 |
---|---|
^ |
在字串開頭開始比對。 |
[^@\s]+ |
比對 @ 字元或空白以外出現一或多次的任何字元。 |
@ |
比對 @ 字元。 |
[^@\s]+ |
比對 @ 字元或空白以外出現一或多次的任何字元。 |
\. |
比對單一句號字元。 |
[^@\s]+ |
比對 @ 字元或空白以外出現一或多次的任何字元。 |
$ |
在字串的結尾結束比對。 |
重要
這個規則運算式目標並非涵蓋有效電子郵件地址的每個層面。 這是做為範例提供,讓您視需要擴充。