ここでは、指定された文字列がメールアドレスとして正しい形式であるか(RFCの規則に従っているか)検証する方法について説明します。
なお、規則に違反したメールアドレスであっても使用はできます。実際に、普通に使用されている規則違反のメールアドレスも多数存在しています。よって、例えばフォームに入力された文字列がメールアドレスか調べるためにここで紹介しているような方法を使うと、実際に使用されているメールアドレスを拒否してしまう可能性があります。そのような事態を避けるために、後述する「正規表現を使用する方法」では、より緩いルールでチェックする方法も紹介します。
補足:メールアドレスが実際に存在しているかを、メールを送信することなく調べる方法としては、SMTPのVRFYコマンドを使用したり、RCPTコマンドが成功するか試すといった方法が考えられます(この時接続するメールサーバーは、「DNSサーバーと直接やり取りして、A、PTR、MX等のレコードを検索する」で紹介しているような方法で、MXレコードを検索して取得します)。しかし、スパム対策のため、多くのメールサーバーではこのような方法が使えないようになっています。よって、メールアドレスが存在するか調べる方法はないと思った方がよいでしょう。
MSDNの「方法 : 文字列が有効な電子メール形式であるかどうかを検証する」には、「電子メール アドレスが有効であるかどうかを判別するには、電子メール アドレスをMailAddress.MailAddress(String) クラス コンストラクターに渡します。」とあります。MailAddressコンストラクター(String)がFormatExceptionをスローした時、メールアドレスは正しくない形式であると判断できます。なお、MailAddressクラスは.NET Framework 2.0以降で使用できます。
「Exchange ブログ JAPAN - TechNet Blogs」によると、この方法はRFC2821とRFC2822(つまり、古い規則)に準拠しているということです。また、.NET Framework 4.0からは、メールアドレスのユーザー名部分で、連続するドット(例えば、「user..name@domain.com」)や末尾のドット(例えば、「user.@domain.com」)が許可されるようになったということです。
補足:同ページによると、メールアドレスのユーザー名部分をダブルコーテーションで囲んだ形式は、.NET Framework 3.5以前では不具合により失敗することがあるということです。これを修正するには、「FIX: You receive a FormatException message when you use the System.Net.Mail class to send e-mail in the .NET Framework 2.0」にあるHotfixを適用します。
MailAddressクラスがサポートしているメールアドレス形式については、MSDNの「MailAddress クラス」にも説明がありますので、そちらも参考にしてください。
以下に、この方法でメールアドレスを検証する具体例を示します。
''' <summary> ''' 指定された文字列がメールアドレスとして正しい形式か検証する ''' </summary> ''' <param name="address">検証する文字列</param> ''' <returns>正しい時はTrue。正しくない時はFalse。</returns> Public Shared Function IsValidMailAddress(address As String) As Boolean If String.IsNullOrEmpty(address) Then Return False End If Try Dim a As New System.Net.Mail.MailAddress(address) Catch ex As FormatException 'FormatExceptionがスローされた時は、正しくない Return False End Try Return True End Function
/// <summary> /// 指定された文字列がメールアドレスとして正しい形式か検証する /// </summary> /// <param name="address">検証する文字列</param> /// <returns>正しい時はTrue。正しくない時はFalse。</returns> public static bool IsValidMailAddress(string address) { if (string.IsNullOrEmpty(address)) { return false; } try { System.Net.Mail.MailAddress a = new System.Net.Mail.MailAddress(address); } catch (FormatException) { //FormatExceptionがスローされた時は、正しくない return false; } return true; }
「is_mail()」というメールアドレスを検証する関数のコードが、New BSD Licenseで公開されています。この関数はphpで書かれていますが、C#に移植されたものも公開されています(C#版は、Java版を移植したものです)。
この関数は、現時点では、RFC5321、RFC5322、RFC4291、RFC1123 SECTION-2.1、RFC2821、RFC2822、RFC3696に従っているということです。
この方法でメールアドレスを検証する具体例を以下に示します。
Dim isEMail As New com.dominicsayers.isemail.IsEMail() 'メールアドレスが正しい形式か調べる If isEMail.IsEmailValid("a.@gmail.com") Then Console.WriteLine("正しいメールアドレスです") Else Console.WriteLine("不正なメールアドレスです") End If
com.dominicsayers.isemail.IsEMail isEMail = new com.dominicsayers.isemail.IsEMail(); //メールアドレスが正しい形式か調べる if (isEMail.IsEmailValid("a.@gmail.com")) { Console.WriteLine("正しいメールアドレスです"); } else { Console.WriteLine("不正なメールアドレスです"); }
注意:ここでは正規表現の説明はしません。.NET Frameworkの正規表現の基本は、「正規表現の基本」で説明しています。また、指定された文字列が正規表現パターンと一致しているかを調べる方法は、「正規表現を使って文字列がある形式と一致するか調べる」で説明しています。
ある文字列がRFCのメールアドレスの規則に従っているかを検証できる単一の正規表現パターンは、存在しないようです。しかしある程度のことならばできます。
例えば、「Mail::RFC822::Address」には、RFC822(かなり古い規則)に従った正規表現パターンが紹介されています。ただしこのパターンは、メールアドレス内のコメントには対応していないということです。
また、RFC5322に従った正規表現パターンとされているものは、「How to Find or Validate an Email Address」や「メールアドレスの正規表現」などで紹介されています。
これらとは別に、様々な正規表現パターンを実際に試して比較したものが、「Comparing E-mail Address Validating Regular Expressions」にあります。このページを見ると、完ぺきなパターンはありませんが、よりよいパターンを探すのに参考になります。
補足:「Comparing E-mail Address Validating Regular Expressions」で現在ベストとされている正規表現パターンは、PHPのfilter_var関数で使用されているパターンです。このパターンには「i」というパターン修飾子が付いているため、大文字小文字を区別しないオプション(RegexOptions.IgnoreCase)が必要です。また「D」というパターン修飾子も付いているため、.NET Frameworkでは、パターン内の「$」を「\z」に置き換えた方がよいでしょう。
このように、メールアドレスの規則は非常に複雑なので、メールアドレスが正しいかを厳密に検証する必要があるのであれば、正規表現は使わずに、それ以前に紹介したような方法を用いた方がよいでしょう。
もしメールアドレスっぽいかを簡単に調べるだけであれば、正規表現はぴったりです。例えば次の例では、「Regular-Expressions.info」で紹介されている正規表現パターンを使用して、指定された文字列がメールアドレスっぽいか調べています。
'検証する文字列 Dim address As String = "a@gmail.com" 'メールアドレスっぽいか調べる If System.Text.RegularExpressions.Regex.IsMatch( _ address, _ "\A[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\z", _ System.Text.RegularExpressions.RegexOptions.IgnoreCase) Then Console.WriteLine("メールアドレスのようです") End If
//検証する文字列 string address = "a@gmail.com"; //メールアドレスっぽいか調べる if (System.Text.RegularExpressions.Regex.IsMatch( address, @"\A[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\z", System.Text.RegularExpressions.RegexOptions.IgnoreCase)) { Console.WriteLine("メールアドレスのようです"); }
上記の正規表現パターンでは、実際に使用されているメールアドレスでも、メールアドレスっぽくないと判断されてしまう可能性が十分にあります。もし、少しでも本当のメールアドレスの可能性があればOKにするというのであれば、さらに緩い正規表現パターンにしてください。例えば、極限まで(?)緩くして、「@の前後に \n 以外の文字がある」かどうかだけを調べるパターンは、「\A.+@.+\z」となります。(「@の前後に制御文字以外の文字がある」かどうかだけを調べるパターンは、「\A\P{Cc}+@\P{Cc}+\z」となります。)
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。