文字列が有効な電子メール形式であるかどうかを検証する方法

この記事の例では、正規表現を使用して文字列の形式が有効な電子メール形式であるかどうかを検証します。

この正規表現は、電子メールとして実際に使用できるものに比べると単純です。 正規表現を使用して電子メールを検証することは、電子メールの構造が正しいことを確認するのに役立ちます。 ただし、実際に電子メールが存在することを確認する代わりにはなりません。

✔️ 小さい正規表現を使用して、電子メールの有効な構造を確認します。

✔️ アプリのユーザーが指定したアドレスにテスト メールを送信します。

❌ 電子メールを検証する唯一の方法として、正規表現を使用しないでください。

電子メールの構造が正しいことを検証するために "完全な" 正規表現を作成しようとすると、正規表現が非常に複雑になり、デバッグや改善が非常に困難になります。 正規表現では、電子メールが正しく構成されていても、それが存在することを検証できません。 電子メールを検証する最善の方法は、そのアドレスにテスト メールを送信することです。

警告

System.Text.RegularExpressions を使用して信頼できない入力を処理するときは、タイムアウトを渡します。 悪意のあるユーザーが RegularExpressions に入力を提供して、サービス拒否攻撃を行う可能性があります。 RegularExpressions を使用する ASP.NET Core フレームワーク API は、タイムアウトを渡します。

次の例では、IsValidEmail メソッドを定義します。このメソッドは、文字列に有効なメール アドレスが含まれている場合には true を返し、含まれていない場合には false を返します。それ以外のアクションは行われません。

電子メール アドレスが有効であることを確認するため、 IsValidEmail メソッドは Regex.Replace(String, String, MatchEvaluator) メソッドを呼び出し、 (@)(.+)$ の正規表現パターンを指定して、電子メール アドレスからドメイン名を切り離します。 3 番目のパラメーターは、一致したテキストを操作また置換するメソッドを表す MatchEvaluator デリゲートです。 正規表現パターンは次のように解釈されます。

Pattern 説明
(@) @ 文字と一致します。 この部分が最初のキャプチャ グループです。
(.+) 任意の文字の 1 回以上の出現に一致します。 この部分が 2 番目のキャプチャ グループです。
$ 入力文字列の末尾で照合を終了します。

ドメイン名は @ 文字と合わせて 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 フラグが使用されます。

Pattern 説明
^ 文字列の先頭から照合を開始します。
[^@\s]+ @ 文字または空白以外の任意の文字の 1 回以上の出現を照合します。
@ @ 文字と一致します。
[^@\s]+ @ 文字または空白以外の任意の文字の 1 回以上の出現を照合します。
\. 1 つのピリオド文字を照合します。
[^@\s]+ @ 文字または空白以外の任意の文字の 1 回以上の出現を照合します。
$ 入力文字列の末尾で照合を終了します。

重要

この正規表現は、有効なメール アドレスのすべての側面をカバーすることを意図したものではありません。 必要に応じて拡張するための例として提供されています。

関連項目