如何驗證字串是否為有效的電子郵件格式

本文範例使用正則表達式來驗證字串是否為有效的電子郵件格式。

這個正則表達式比實際可用作電子郵件的表達方式簡單許多。 使用正則表達式來驗證電子郵件有助於確保郵件結構正確。 然而,這並不等於驗證該電子郵件是否真實存在。

✔️ 請使用小型正則表達式來檢查電子郵件的有效結構。

✔️ 請務必寄送測試郵件到你應用程式使用者提供的地址。

❌ 千萬不要只用正規表達式來驗證郵件。

如果你試圖創造 完美的 正則表達式來驗證電子郵件結構是否正確,這個表達式會變得非常複雜,難以除錯或改進。 正規表達式無法驗證電子郵件的存在,即使郵件結構正確。 驗證電子郵件的最佳方法是寄出測試郵件到該地址。

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

這個正則表達式並非旨在涵蓋有效電子郵件地址的所有面向。 這是作為範例,供你根據需要延伸。

另請參閱