方法: 文字列が有効な電子メール形式であるかどうかを検証するHow to: Verify that Strings Are in Valid Email Format

正規表現を使用して文字列の形式が有効な電子メール形式であるかどうかを検証する例を次に示します。The following example uses a regular expression to verify that a string is in valid email format.

Example

次の例では、 IsValidEmail メソッドを定義します。このメソッドは、文字列に有効な電子メール アドレスが含まれている場合に true を返し、含まれていない場合に false を返します。それ以外の動作は行いません。The example defines an IsValidEmail method, which returns true if the string contains a valid email address and false if it does not, but takes no other action.

電子メール アドレスが有効であることを確認するため、 IsValidEmail メソッドは Regex.Replace(String, String, MatchEvaluator) メソッドを呼び出し、 (@)(.+)$ の正規表現パターンを指定して、電子メール アドレスからドメイン名を切り離します。To verify that the email address is valid, the IsValidEmail method calls the Regex.Replace(String, String, MatchEvaluator) method with the (@)(.+)$ regular expression pattern to separate the domain name from the email address. 3 番目のパラメーターは、一致したテキストを操作また置換するメソッドを表す MatchEvaluator デリゲートです。The third parameter is a MatchEvaluator delegate that represents the method that processes and replaces the matched text. 正規表現パターンは次のように解釈されます。The regular expression pattern is interpreted as follows.

パターンPattern 説明Description
(@) @ 文字と一致します。Match the @ character. これが最初のキャプチャ グループです。This is the first capturing group.
(.+) 任意の文字の 1 回以上の出現に一致します。Match one or more occurrences of any character. これが 2 番目のキャプチャ グループです。This is the second capturing group.
$ 入力文字列の末尾で照合を終了します。End the match at the end of the string.

ドメイン名は @ 文字と合わせて DomainMapper メソッドに渡されます。このメソッドは IdnMapping クラスを使用して、US-ASCII 文字の範囲に含まれない Unicode 文字を Punycode に変換します。The domain name along with the @ character is passed to the DomainMapper method, which uses the IdnMapping class to translate Unicode characters that are outside the US-ASCII character range to Punycode. また、このメソッドは、 invalid メソッドがドメイン名に無効な文字を検出すると、 True フラグを IdnMapping.GetAscii に設定します。The method also sets the invalid flag to True if the IdnMapping.GetAscii method detects any invalid characters in the domain name. このメソッドは、Punycode ドメイン名の前に @ 記号を付けて、これを IsValidEmail メソッドに返します。The method returns the Punycode domain name preceded by the @ symbol to the IsValidEmail method.

次に、 IsValidEmail メソッドは Regex.IsMatch(String, String) メソッドを呼び出して、電子メール アドレスが正規表現パターンに準拠するかどうかを確認します。The IsValidEmail method then calls the Regex.IsMatch(String, String) method to verify that the address conforms to a regular expression pattern.

IsValidEmail メソッドは、認証によって電子メール アドレスを検証するわけではありません。Note that the IsValidEmail method does not perform authentication to validate the email address. 電子メール アドレスの形式として有効かどうかを判断しているだけです。It merely determines whether its format is valid for an email address. さらに、 IsValidEmail メソッドは、最上位ドメイン名が IANA ルート ゾーン データベースに掲載されている有効なドメイン名であることを確認しません (これには検索操作が必要です)。In addition, the IsValidEmail method does not verify that the top-level domain name is a valid domain name listed at the IANA Root Zone Database, which would require a look-up operation. 代わりに、正規表現によって単に最上位ドメイン名が 2 ~ 24 文字の ASCII 英数字で構成されており、最初の文字と末尾の文字は英数字、その他の文字は英数字またはハイフン (-) であることを確認します。Instead, the regular expression merely verifies that the top-level domain name consists of between two and twenty-four ASCII characters, with alphanumeric first and last characters and the remaining characters being either alphanumeric or a hyphen (-).

using System;
using System.Globalization;
using System.Text.RegularExpressions;

public 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)
                var 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,
                @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
                @"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-0-9a-z]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$",
                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,
                                 "^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
                                 "(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-0-9a-z]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$",
                                 RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250))

        Catch e As RegexMatchTimeoutException
            Return False

        End Try

    End Function

End Class

この例の正規表現パターン ^(?(")(".+?(?<!\\)"@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`{}|~\w])*)(?<=[0-9a-z])@))(?([)([(\d{1,3}.){3}\d{1,3}])|(([0-9a-z][-0-9a-z]*[0-9a-z]*.)+[a-z0-9][-a-z0-9]{0,22}[a-z0-9]))$ の意味を次の表に示します。In this example, the regular expression pattern ^(?(")(".+?(?<!\\)"@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`{}|~\w])*)(?<=[0-9a-z])@))(?([)([(\d{1,3}.){3}\d{1,3}])|(([0-9a-z][-0-9a-z]*[0-9a-z]*.)+[a-z0-9][-a-z0-9]{0,22}[a-z0-9]))$ is interpreted as shown in the following table. 正規表現のコンパイルでは、 RegexOptions.IgnoreCase フラグが使用されることに注意してください。Note that the regular expression is compiled using the RegexOptions.IgnoreCase flag.

パターンPattern 説明Description
^ 文字列の先頭から照合を開始します。Begin the match at the start of the string.
(?(") 最初の文字が引用符であるかどうかを確認します。Determine whether the first character is a quotation mark. (?(") は代替構成体の開始位置です。is the beginning of an alternation construct.
(?("")("".+?(?<!\\)""@) 最初の文字が引用符である場合、始まりの引用符に続く 1 つ以上の任意の文字と終わりの引用符に一致します。If the first character is a quotation mark, match a beginning quotation mark followed by at least one occurrence of any character, followed by an ending quotation mark. 終わりの引用符の前には円記号 (\) を使用できません。The ending quotation mark must not be preceded by a backslash character (\). (?<! はゼロ幅の否定先読みアサーションの開始です。is the beginning of a zero-width negative lookbehind assertion. 文字列はアット マーク (@) で終わる必要があります。The string should conclude with an at sign (@).
|(([0-9a-z] 最初の文字が引用符でない場合は、a ~ z または A ~ Z の任意の英字または 0 ~ 9 の任意の数字と一致します (比較では大文字小文字は区別されません)。If the first character is not a quotation mark, match any alphabetic character from a to z or A to Z (the comparison is case insensitive), or any numeric character from 0 to 9.
(\.(?!\.)) 次の文字がピリオドの場合は、その文字と一致します。If the next character is a period, match it. ピリオドでない場合は、次の文字を先読みして照合を継続します。If it is not a period, look ahead to the next character and continue the match. (?!\.) は、2 つの連続するピリオドが電子メール アドレスのローカル部分に出現することを防ぐゼロ幅の負の先読みアサーションです。is a zero-width negative lookahead assertion that prevents two consecutive periods from appearing in the local part of an email address.
|[-!#$%&'*+/=?^`{}|~\w] 次の文字がピリオドでない場合は、任意の単語文字または -!#$%'*+=?^`{}|~ のいずれかの文字と一致します。 If the next character is not a period, match any word character or one of the following characters: -!#$%'*+=?^`{}|~.
((.(?!.))|[-!#$%'*+/=?^`{}|~\w])* 0 回以上の代替パターン (ピリオドとそれに続くピリオド以外の文字、または複数の文字のうちのいずれかの 1 文字) と一致します。 Match the alternation pattern (a period followed by a non-period, or one of a number of characters) zero or more times.
@ @ 文字と一致します。Match the @ character.
(?<=[0-9a-z]) @ 文字の前にくる文字が A ~ Z、a ~ z、または 0 ~ 9 である場合に照合を継続します。Continue the match if the character that precedes the @ character is A through Z, a through z, or 0 through 9. (?<=[0-9a-z]) 構成体は、ゼロ幅の正の後読みアサーションを定義します。The (?<=[0-9a-z]) construct defines a zero-width positive lookbehind assertion.
(?(\[) @ に続く文字が左角かっこかどうかを確認します。Check whether the character that follows @ is an opening bracket.
(\[(\d{1,3}\.){3}\d{1,3}\]) 左角かっこの場合は、左角かっこ、それに続く IP アドレス (各セットがピリオドで区切られた、4 セットの 1 ~ 3 桁の数字)、および右角かっこと一致します。If it is an opening bracket, match the opening bracket followed by an IP address (four sets of one to three digits, with each set separated by a period) and a closing bracket.
|(([0-9a-z][-0-9a-z][0-9a-z].)+ @ に続く文字が左角かっこでない場合は、値が A - Z、a - z、または 0 - 9 の 1 つの英数字の後に、ハイフンの 0 回以上の出現、A - Z、a - z、または 0 - 9 の値の 0 個または 1 つの英数字、さらにピリオドが続くパターンと一致します。If the character that follows @ is not an opening bracket, match one alphanumeric character with a value of A-Z, a-z, or 0-9, followed by zero or more occurrences of a hyphen, followed by zero or one alphanumeric character with a value of A-Z, a-z, or 0-9, followed by a period. このパターンは 1 回以上繰り返すことができ、後ろに最上位ドメイン名が続く必要があります。This pattern can be repeated one or more times, and must be followed by the top-level domain name.
[a-z0-9][\-a-z0-9]{0,22}[a-z0-9])) 最上位ドメイン名では、最初の文字と最後の文字が英数字文字 (a ~ z、A ~ Z、0 ~ 9) である必要があります。The top-level domain name must begin and end with an alphanumeric character (a-z, A-Z, and 0-9). また、0 ~ 22 文字の ASCII 文字 (英数字またはハイフン) を含めることができます。It can also include from zero to 22 ASCII characters that are either alphanumeric or hyphens.
$ 入力文字列の末尾で照合を終了します。End the match at the end of the string.

コードのコンパイルCompiling the Code

IsValidEmail メソッドと DomainMapper メソッドは、正規表現ユーティリティ メソッドのライブラリに含めることができるほか、アプリケーション クラス内のプライベートな静的メソッドやインスタンス メソッドとして含めることもできます。The IsValidEmail and DomainMapper methods can be included in a library of regular expression utility methods, or they can be included as private static or instance methods in the application class.

これらを正規表現ライブラリに含めるには、Visual Studio のクラス ライブラリ プロジェクトにコードをコピーして貼り付けるか、コードをテキスト ファイルにコピーして貼り付けて、次のようなコマンドでコマンド ラインからコンパイルします (ソース コード ファイルの名前を RegexUtilities.cs または RegexUtilities.vb と仮定しています)。To include them in a regular expression library, either copy and paste the code into a Visual Studio Class Library project, or copy and paste it into a text file and compile it from the command line with a command like the following (assuming that the name of the source code file is RegexUtilities.cs or RegexUtilities.vb:

csc /t:library RegexUtilities.cs  
vbc /t:library RegexUtilities.vb  

また、 Regex.CompileToAssembly メソッドを使用して、この正規表現を正規表現ライブラリに追加できます。You can also use the Regex.CompileToAssembly method to include this regular expression in a regular expression library.

正規表現ライブラリ内で使用した場合は、次のようなコードを使用して呼び出すことができます。If they are used in a regular expression library, you can call them by using code such as the following:

class Program
{
    static void Main(string[] args)
    {
        string[] emailAddresses = { "david.jones@proseware.com", "d.j@server1.proseware.com",
                                    "jones@ms1.proseware.com", "j.@server1.proseware.com",
                                    "j@proseware.com9", "js#internal@proseware.com",
                                    "j_9@[129.126.118.1]", "j..s@proseware.com",
                                    "js*@proseware.com", "js@proseware..com",
                                    "js@proseware.com9", "j.s@server1.proseware.com",
                                    "\"j\\\"s\\\"\"@proseware.com", "js@contoso.中国" };

        foreach (var emailAddress in emailAddresses)
        {
            if (RegexUtilities.IsValidEmail(emailAddress))
                Console.WriteLine($"Valid:   {emailAddress}");
            else
                Console.WriteLine($"Invalid: {emailAddress}");
        }

        Console.ReadKey();
    }
}
// The example displays the following output:
//       Valid: david.jones@proseware.com
//       Valid: d.j@server1.proseware.com
//       Valid: jones@ms1.proseware.com
//       Invalid: j.@server1.proseware.com
//       Valid: j@proseware.com9
//       Valid: js#internal@proseware.com
//       Valid: j_9@[129.126.118.1]
//       Invalid: j..s@proseware.com
//       Invalid: js*@proseware.com
//       Invalid: js@proseware..com
//       Valid: js@proseware.com9
//       Valid: j.s@server1.proseware.com
//       Valid: "j\"s\""@proseware.com
//       Valid: js@contoso.中国
Public Class Application
   Public Shared Sub Main()
      Dim emailAddresses() As String = {"david.jones@proseware.com", "d.j@server1.proseware.com",
                                       "jones@ms1.proseware.com", "j.@server1.proseware.com",
                                       "j@proseware.com9", "js#internal@proseware.com",
                                       "j_9@[129.126.118.1]", "j..s@proseware.com",
                                       "js*@proseware.com", "js@proseware..com",
                                       "js@proseware.com9", "j.s@server1.proseware.com",
                                       """j\""s\""""@proseware.com", "js@contoso.中国"}

      For Each emailAddress As String In emailAddresses
         If RegexUtilities.IsValidEmail(emailAddress) Then
               Console.WriteLine($"Valid:   {emailAddress}")
         Else
               Console.WriteLine($"Invalid: {emailAddress}")
         End If
      Next
   End Sub
End Class
' The example displays the following output:
'       Valid: david.jones@proseware.com
'       Valid: d.j@server1.proseware.com
'       Valid: jones@ms1.proseware.com
'       Invalid: j.@server1.proseware.com
'       Valid: j@proseware.com9
'       Valid: js#internal@proseware.com
'       Valid: j_9@[129.126.118.1]
'       Invalid: j..s@proseware.com
'       Invalid: js*@proseware.com
'       Invalid: js@proseware..com
'       Valid: js@proseware.com9
'       Valid: j.s@server1.proseware.com
'       Valid: "j\"s\""@proseware.com
'       Valid: js@contoso.中国

電子メール検証の正規表現を含む RegexUtilities.dll という名前のクラス ライブラリを作成してあると仮定した場合、この例は次の方法のいずれかでコンパイルできます。Assuming you've created a class library named RegexUtilities.dll that includes your email validation regular expression, you can compile this example in either of the following ways:

  • Visual Studio では、コンソール アプリケーションを作成して、RegexUtilities.dll への参照をプロジェクトに追加します。In Visual Studio, by creating a Console Application and adding a reference to RegexUtilities.dll to your project.

  • コマンド ラインからは、ソース コードをテキスト ファイルにコピーして貼り付け、次のようなコマンドでコンパイルします (ソース コード ファイルの名前を Example.cs または Example.vb と仮定しています)。From the command line, by copying and pasting the source code into a text file and compiling it with a command like the following (assuming that the name of the source code file is Example.cs or Example.vb:

    csc Example.cs /r:RegexUtilities.dll  
    
    vbc Example.vb /r:RegexUtilities.dll  
    

関連項目See also