文字列が有効な電子メール アドレスであることを検証する最も洗練されたコードは何ですか?
45 に答える
これはどうですか?
bool IsValidEmail(string email)
{
var trimmedEmail = email.Trim();
if (trimmedEmail.EndsWith(".")) {
return false; // suggested by @TK-421
}
try {
var addr = new System.Net.Mail.MailAddress(email);
return addr.Address == trimmedEmail;
}
catch {
return false;
}
}
Stuart のコメントによると、これは常に true を返すのではなく、最終的なアドレスを元の文字列と比較します。MailAddress は、スペースを含む文字列を "表示名" と "アドレス" の部分に解析しようとするため、元のバージョンでは誤検知が返されていました。
明確にするために、質問は特定の文字列が電子メール アドレスの有効な表現であるかどうかを尋ねているのであって、電子メール アドレスがメッセージを送信するための有効な宛先であるかどうかではありません。そのための唯一の現実的な方法は、確認メッセージを送信することです。
電子メール アドレスは、最初に想定するよりも寛大であることに注意してください。これらはすべて完全に有効な形式です。
- コグ@ホイール
- "オレンジ色の歯車"@example.com
- 123@$.xyz
ほとんどのユースケースでは、偽の「無効」は、偽の「有効」よりもユーザーと将来の証明にとってはるかに悪いものです。これは、この質問に対する受け入れられた回答であった記事です(その回答はその後削除されました)。問題を解決する方法について、より多くの詳細と他のいくつかのアイデアがあります。
サニティ チェックを提供することは、ユーザー エクスペリエンスにとって依然として良い考えです。電子メール アドレスが有効であると仮定すると、既知のトップ レベル ドメインを探したり、MX レコードのドメインをチェックしたり、一般的なドメイン名 (gmail.cmo) のスペル ミスをチェックしたりできます。次に、ユーザーに警告を表示します。 「はい、私のメール サーバーは実際にメール アドレスとして許可しています」と言うチャンスです。
ビジネス ロジックに例外処理を使用することについては、避けるべきことだと思います。しかし、これは、利便性と明快さがドグマを上回る可能性があるケースの 1 つです。
さらに、電子メール アドレスを使用して何か他のことを行う場合、おそらくそれを MailAddress に変換する必要があります。この正確な関数を使用しない場合でも、おそらく同じパターンを使用したいと思うでしょう。null、空、無効な形式など、さまざまな例外をキャッチすることで、特定の種類のエラーをチェックすることもできます。
- - 参考文献 - -
これは古い質問ですが、最近のものを含め、SOで見つけたすべての回答は、この質問と同様に回答されています。ただし、.Net 4.5 / MVC 4 では、System.ComponentModel.DataAnnotations から [EmailAddress] 注釈を追加することでフォームに電子メール アドレスの検証を追加できるため、.ネット全般。
これは機能しているようで、私にはかなりエレガントに思えます:
using System.ComponentModel.DataAnnotations;
class ValidateSomeEmails
{
static void Main(string[] args)
{
var foo = new EmailAddressAttribute();
bool bar;
bar = foo.IsValid("someone@somewhere.com"); //true
bar = foo.IsValid("someone@somewhere.co.uk"); //true
bar = foo.IsValid("someone+tag@somewhere.net"); //true
bar = foo.IsValid("futureTLD@somewhere.fooo"); //true
bar = foo.IsValid("fdsa"); //false
bar = foo.IsValid("fdsa@"); //false
bar = foo.IsValid("fdsa@fdsa"); //false
bar = foo.IsValid("fdsa@fdsa."); //false
//one-liner
if (new EmailAddressAttribute().IsValid("someone@somewhere.com"))
bar = true;
}
}
個人的には、そこに @ 記号があり、おそらく . キャラクター。さまざまな正確さで使用できる多くの正規表現がありますが、これらのほとんどは有効な電子メール アドレスを除外するか、無効なものを通過させると思います。偽のメール アドレスを入力したい場合は、偽のアドレスを入力します。電子メール アドレスが正当であり、その人物がその電子メール アドレスを管理していることを確認する必要がある場合は、それが実際のアドレスであることを確認できるように、特別なコード化されたリンクを含む電子メールを送信する必要があります。
以下の方法がベストだと思います。
public static bool EmailIsValid(string email)
{
string expression = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
if (Regex.IsMatch(email, expression))
{
if (Regex.Replace(email, expression, string.Empty).Length == 0)
{
return true;
}
}
return false;
}
この静的関数を一般クラスに含めることができます。
最も洗練された方法は、.Net の組み込みメソッドを使用することです。
これらの方法:
試され、テストされています。これらの方法は、私自身のプロのプロジェクトで使用されています。
信頼性が高く高速な正規表現を内部で使用します。
C# 用に Microsoft によって作成されました。車輪を再発明する必要はありません。
bool の結果を返します。True は、電子メールが有効であることを意味します。
.Net 4.5 以降のユーザー向け
この参照をプロジェクトに追加します。
System.ComponentModel.DataAnnotations
これで、次のコードを使用できます。
(new EmailAddressAttribute().IsValid("youremailhere@test.test"));
使用例
宣言するいくつかのメソッドを次に示します。
protected List<string> GetRecipients() // Gets recipients from TextBox named `TxtRecipients`
{
List<string> MethodResult = null;
try
{
List<string> Recipients = TxtRecipients.Text.Replace(",",";").Replace(" ", "").Split(';').ToList();
List<string> RecipientsCleaned = new List<string>();
foreach (string Recipient in RecipientsCleaned)
{
if (!String.IsNullOrWhiteSpace(Recipient))
{
RecipientsNoBlanks.Add(Recipient);
}
}
MethodResult = RecipientsNoBlanks;
}
catch//(Exception ex)
{
//ex.HandleException();
}
return MethodResult;
}
public static bool IsValidEmailAddresses(List<string> recipients)
{
List<string> InvalidAddresses = GetInvalidEmailAddresses(recipients);
return InvalidAddresses != null && InvalidAddresses.Count == 0;
}
public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
List<string> MethodResult = null;
try
{
List<string> InvalidEmailAddresses = new List<string>();
foreach (string Recipient in recipients)
{
if (!(new EmailAddressAttribute().IsValid(Recipient)) && !InvalidEmailAddresses.Contains(Recipient))
{
InvalidEmailAddresses.Add(Recipient);
}
}
MethodResult = InvalidEmailAddresses;
}
catch//(Exception ex)
{
//ex.HandleException();
}
return MethodResult;
}
...そして、それらの動作を示すコード:
List<string> Recipients = GetRecipients();
bool IsValidEmailAddresses = IsValidEmailAddresses(Recipients);
if (IsValidEmailAddresses)
{
//Emails are valid. Your code here
}
else
{
StringBuilder sb = new StringBuilder();
sb.Append("The following addresses are invalid:");
List<string> InvalidEmails = GetInvalidEmailAddresses(Recipients);
foreach (string InvalidEmail in InvalidEmails)
{
sb.Append("\n" + InvalidEmail);
}
MessageBox.Show(sb.ToString());
}
さらに、この例:
- セミコロンで区切られた 0 個、1 個、または多数の電子メール アドレスを含むために単一の文字列が使用されるため、仕様を超えて拡張されます
;
。 - EmailAddressAttribute オブジェクトの IsValid メソッドの使用方法を明確に示しています。
4.5 未満の .Net のバージョンのユーザー向けの代替手段
.Net 4.5 が利用できない状況では、次の解決策を使用します。
具体的には、次を使用します。
public static bool IsValidEmailAddress(string emailAddress)
{
bool MethodResult = false;
try
{
MailAddress m = new MailAddress(emailAddress);
MethodResult = m.Address == emailAddress;
}
catch //(Exception ex)
{
//ex.HandleException();
}
return MethodResult;
}
public static List<string> GetInvalidEmailAddresses(List<string> recipients)
{
List<string> MethodResult = null;
try
{
List<string> InvalidEmailAddresses = new List<string>();
foreach (string Recipient in recipients)
{
if (!IsValidEmail(Recipient) && !InvalidEmailAddresses.Contains(Recipient))
{
InvalidEmailAddresses.Add(Recipient);
}
}
MethodResult = InvalidEmailAddresses;
}
catch //(Exception ex)
{
//ex.HandleException();
}
return MethodResult;
}
正直なところ、本番コードでは、@
シンボルをチェックするのが最善です。
私は電子メールを完全に検証する場所にいることはありません。それが本当に有効かどうかを私がどのように確認するか知っていますか?送られた場合。そうでなければ、それは悪いことです。もしそうなら、人生は良いことです。私が知る必要があるのはそれだけです。
この正規表現は、@ マーク以外のものをチェックすることと、奇妙なエッジ ケースを受け入れることとの間の適切なトレードオフであることがわかりました。
^[^@\s]+@[^@\s]+(\.[^@\s]+)+$
少なくとも @ マークの周りに何かを配置し、少なくとも通常の外観のドメインを配置します。
メールアドレスの検証は、思ったほど簡単ではありません。正規表現だけを使用して電子メール アドレスを完全に検証することは、実際には理論的に不可能です。
この件に関する議論と FParsec を使用した F# の実装については、私のブログ記事を参照してください。[/恥知らずのプラグ]
あなたが本当にそして私が本当にメールアドレスが有効であるかどうか知りたいのなら...それを証明するためにメールエクスチェンジャーに頼んでください、正規表現は必要ありません。リクエストがあればコードを提供できます。
一般的な手順は次のとおりです。1。メールアドレスにドメイン名の部分がありますか?(@> 0のインデックス)2。DNSクエリを使用してドメインにメールエクスチェンジャーがあるかどうかを確認します3.メールエクスチェンジャーへのtcp接続を開きます4. smtpプロトコルを使用して、受信者として電子メールアドレスを使用してサーバーへのメッセージを開きます5。サーバーの応答を解析します。6.ここまで到達したら、メッセージを終了します。すべてが良好です。
これはご想像のとおり、時間的には非常に高価で、SMTPに依存していますが、機能します。
一般的に言えば、電子メール アドレスを検証するための正規表現を思いつくのは簡単なことではありません。この記事の執筆時点では、電子メール アドレスの構文は比較的多数の標準に従う必要があり、それらすべてを正規表現内に実装することは事実上不可能です。
現在のすべての IETF 標準 (RFC 1123、RFC 2821、RFC 2822、RFC 3696、RFC 4291、RFC 5321、および RFC 5322)に従って電子メール アドレスを検証できる成熟した .NET ライブラリであるEmailVerify.NETを試すことを強くお勧めします。、関連する DNS レコードをテストし、ターゲット メールボックスがメッセージを受け入れることができるかどうかを確認し、特定のアドレスが使い捨てかどうかを判断することさえできます。
免責事項: 私はこのコンポーネントの主任開発者です。
/「new EmailAddressAttribute();」の作成に使用される内部正規表現の使用 .Net4.5 のコンポーネント >>> System.ComponentModel.DataAnnotations を使用。//電子メール アドレスを検証するには......テスト済みで機能しています。
public bool IsEmail(string email)
{
if (String.IsNullOrEmpty(email))
{ return false; }
try
{
Regex _regex = new Regex("^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])" +
"+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)" +
"((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|" +
"[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\u" +
"FDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|" +
"(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|" +
"[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900" +
"-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFF" +
"EF])))\\.?$", RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled);
return _regex.IsMatch(email);
}
catch (RegexMatchTimeoutException)
{
return false;
}
}
また、これを使用できます:
http://msdn.microsoft.com/en-us/library/01escwtf(v=vs.110).aspx
次の方法で、電子メール文字列の形式が正しいか間違っているかを確認しますSystem.Text.RegularExpressions
。
public static bool IsValidEmailId(string InputEmail)
{
Regex regex = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
Match match = regex.Match(InputEmail);
if (match.Success)
return true;
else
return false;
}
protected void Email_TextChanged(object sender, EventArgs e)
{
String UserEmail = Email.Text;
if (IsValidEmailId(UserEmail))
{
Label4.Text = "This email is correct formate";
}
else
{
Label4.Text = "This email isn't correct formate";
}
}
コンマ、コメント、Unicode 文字、および IP(v4) ドメイン アドレスを正常に検証するため、この正規表現を使用することになりました。
有効なアドレスは次のとおりです。
" "@example.org
(コメント)test@example.org
тест@example.org
ტესტი@example.org
test@[192.168.1.1]
public const string REGEX_EMAIL = @"^(((\([\w!#$%&'*+\/=?^_`{|}~-]*\))?[^<>()[\]\\.,;:\s@\""]+(\.[^<>()[\]\\.,;:\s@\""]+)*)|(\"".+\""))(\([\w!#$%&'*+\/=?^_`{|}~-]*\))?@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$";
js ではなく C# の正規表現には文化の問題があります。そのため、メール チェックには US モードで正規表現を使用する必要があります。ECMAScript モードを使用しない場合、言語の特殊文字は正規表現を使用して AZ で暗示されます。
Regex.IsMatch(email, @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9_\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$", RegexOptions.ECMAScript)
Poyson 1の答えを次のように簡潔にまとめました。
public static bool IsValidEmailAddress(string candidateEmailAddr)
{
string regexExpresion = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
return (Regex.IsMatch(candidateEmailAddr, regexExpresion)) &&
(Regex.Replace(candidateEmailAddr, regexExpresion, string.Empty).Length == 0);
}
メールが有効かどうかをチェックする関数を書きました。ほとんどの場合、私にとってはうまく機能しているようです。
結果:
dasddas-@.com => FALSE
-asd@das.com => FALSE
as3d@dac.coas- => FALSE
dsq!a?@das.com => FALSE
_dasd@sd.com => FALSE
dad@sds => FALSE
asd-@asd.com => FALSE
dasd_-@jdas.com => FALSE
asd@dasd@asd.cm => FALSE
da23@das..com => FALSE
_dasd_das_@9.com => FALSE
d23d@da9.co9 => TRUE
dasd.dadas@dasd.com => TRUE
dda_das@das-dasd.com => TRUE
dasd-dasd@das.com.das => TRUE
コード:
private bool IsValidEmail(string email)
{
bool valid = false;
try
{
var addr = new System.Net.Mail.MailAddress(email);
valid = true;
}
catch
{
valid = false;
goto End_Func;
}
valid = false;
int pos_at = email.IndexOf('@');
char checker = Convert.ToChar(email.Substring(pos_at + 1, 1));
var chars = "qwertyuiopasdfghjklzxcvbnm0123456789";
foreach (char chr in chars)
{
if (checker == chr)
{
valid = true;
break;
}
}
if (valid == false)
{
goto End_Func;
}
int pos_dot = email.IndexOf('.', pos_at + 1);
if(pos_dot == -1)
{
valid = false;
goto End_Func;
}
valid = false;
try
{
checker = Convert.ToChar(email.Substring(pos_dot + 1, 1));
foreach (char chr in chars)
{
if (checker == chr)
{
valid = true;
break;
}
}
}
catch
{
valid = false;
goto End_Func;
}
Regex valid_checker = new Regex(@"^[a-zA-Z0-9_@.-]*$");
valid = valid_checker.IsMatch(email);
if (valid == false)
{
goto End_Func;
}
List<int> pos_list = new List<int> { };
int pos = 0;
while (email.IndexOf('_', pos) != -1)
{
pos_list.Add(email.IndexOf('_', pos));
pos = email.IndexOf('_', pos) + 1;
}
pos = 0;
while (email.IndexOf('.', pos) != -1)
{
pos_list.Add(email.IndexOf('.', pos));
pos = email.IndexOf('.', pos) + 1;
}
pos = 0;
while (email.IndexOf('-', pos) != -1)
{
pos_list.Add(email.IndexOf('-', pos));
pos = email.IndexOf('-', pos) + 1;
}
int sp_cnt = pos_list.Count();
pos_list.Sort();
for (int i = 0; i < sp_cnt - 1; i++)
{
if (pos_list[i] + 1 == pos_list[i + 1])
{
valid = false;
break;
}
if (pos_list[i]+1 == pos_at || pos_list[i]+1 == pos_dot)
{
valid = false;
break;
}
}
if(valid == false)
{
goto End_Func;
}
if (pos_list[sp_cnt - 1] == email.Length - 1 || pos_list[0] == 0)
{
valid = false;
}
End_Func:;
return valid;
}
複数のソリューションを組み合わせて完璧なコードを作成したらどうなるでしょうか?
ランクとレビューが最も高い上位 2 つのソリューションを取得し、それらを組み合わせてより正確な回答を得ました。その短く、速く、愛らしい。
public static bool isValidEmail(string email)
{
try
{
var addr = new System.Net.Mail.MailAddress(email);
if (addr.Address == email)
{
string expression = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
if (Regex.IsMatch(email, expression))
{
if (Regex.Replace(email, expression, string.Empty).Length == 0)
return true;
}
return false;
}
return false;
}
catch
{
return false;
}
}
EmailAddressValidationAttribute
少し前に、フォームの比較的通常の電子メールアドレスのほとんどを適切に検証する必要がある を書きました
local-part@domain
ですSystem.ComponentModel.DataAnnotations.ValidationAttribute
ので使い方は至ってシンプルです。
そして、すべての RFC と正誤表を掘り下げて、すべてのルールを適切に列挙するために必要なすべてのビットを組み立てるのは...面倒です。せいぜい! — ソース コードのC# 電子メール アドレス検証に関する質問への回答に、バリデーターのソース コードを投稿しました。
私のバリデーターは想像を絶するほど完璧ではありませんが、まず第一に、クライアント側の JavaScript 検証を発行するための組み込みサポートはありませんが、それを追加することはそれほど難しくありません.上記の私の答え:
これが私が書いた検証属性です。ほとんどすべての「生の」メールアドレス、つまりlocal-part@domainの形式のものを検証します。RFC で許可されているその他のより創造的な構造はサポートしていません (このリストは決して包括的ではありません)。
- コメント (例:
jsmith@whizbang.com (work)
)- 引用符で囲まれた文字列 (アトムで許可されていない文字を許可するためのエスケープされたテキスト)
- ドメイン リテラル (例:
foo@[123.45.67.012]
)- bang-paths (別名ソース ルーティング)
- 角度アドレス (例
John Smith <jsmith@whizbang.com>
)- 折りたたみ空白
- ローカル部分またはドメインのいずれかの 2 バイト文字(7 ビット ASCII のみ)。
- 等
このように表現できるほとんどすべての電子メールアドレスを受け入れる必要があります
foo.bar@bazbat.com
引用符 (
"
)、山かっこ ('<>')、または角かっこ ( )を使用する必要はありませ[]
ん。ドメインの右端の dns ラベルが有効な TLD (トップレベル ドメイン)であることを検証する試みは行われません。これは、TLD のリストが現在、「ビッグ 6」(.com、.edu、.gov、.mil、.net、.org) に 2 文字の ISO 国コードを加えたものよりもはるかに大きいためです。 ICANN は実際に TLD リストを毎日更新していますが、リストは実際には毎日変更されていないと思います。さらに、[ICANN は一般的な TLD 名前空間の大幅な拡張を承認した][2])。また、一部の電子メール アドレスには、TLD として認識できるものがありません (
postmaster@.
理論的に有効であり、郵送可能であることをご存知ですか? そのアドレスへのメールは、DNS ルート ゾーンのポストマスターに配信されるはずです)。ドメイン リテラルをサポートするように正規表現を拡張することは、それほど難しくありません。
ウィキペディアの文書化されたルールとサンプル アドレスに基づいて、電子メール アドレスの検証ルーチンを作成しました。もう少しコードを見ても構わない人は、どうぞ。正直なところ、メールアドレスの仕様にどれだけクレイジーなルールがあるかわかりませんでした。ホスト名または IP アドレスを完全に検証するわけではありませんが、それでもウィキペディアのすべてのテスト ケースに合格しています。
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace EmailValidateUnitTests
{
[TestClass]
public class EmailValidationUnitTests
{
[TestMethod]
public void TestEmailValidate()
{
// Positive Assertions
Assert.IsTrue("prettyandsimple@example.com".IsValidEmailAddress());
Assert.IsTrue("very.common@example.com".IsValidEmailAddress());
Assert.IsTrue("disposable.style.email.with+symbol@example.com".IsValidEmailAddress());
Assert.IsTrue("other.email-with-dash@example.com".IsValidEmailAddress());
Assert.IsTrue("\"much.more unusual\"@example.com".IsValidEmailAddress());
Assert.IsTrue("\"very.unusual.@.unusual.com\"@example.com".IsValidEmailAddress()); //"very.unusual.@.unusual.com"@example.com
Assert.IsTrue("\"very.(),:;<>[]\\\".VERY.\\\"very@\\\\ \\\"very\\\".unusual\"@strange.example.com".IsValidEmailAddress()); //"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com
Assert.IsTrue("admin@mailserver1".IsValidEmailAddress());
Assert.IsTrue("#!$%&'*+-/=?^_`{}|~@example.org".IsValidEmailAddress());
Assert.IsTrue("\"()<>[]:,;@\\\\\\\"!#$%&'*+-/=?^_`{}| ~.a\"@example.org".IsValidEmailAddress()); //"()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a"@example.org
Assert.IsTrue("\" \"@example.org".IsValidEmailAddress()); //" "@example.org (space between the quotes)
Assert.IsTrue("example@localhost".IsValidEmailAddress());
Assert.IsTrue("example@s.solutions".IsValidEmailAddress());
Assert.IsTrue("user@com".IsValidEmailAddress());
Assert.IsTrue("user@localserver".IsValidEmailAddress());
Assert.IsTrue("user@[IPv6:2001:db8::1]".IsValidEmailAddress());
Assert.IsTrue("user@[192.168.2.1]".IsValidEmailAddress());
Assert.IsTrue("(comment and stuff)joe@gmail.com".IsValidEmailAddress());
Assert.IsTrue("joe(comment and stuff)@gmail.com".IsValidEmailAddress());
Assert.IsTrue("joe@(comment and stuff)gmail.com".IsValidEmailAddress());
Assert.IsTrue("joe@gmail.com(comment and stuff)".IsValidEmailAddress());
// Failure Assertions
Assert.IsFalse("joe(fail me)smith@gmail.com".IsValidEmailAddress());
Assert.IsFalse("joesmith@gma(fail me)il.com".IsValidEmailAddress());
Assert.IsFalse("joe@gmail.com(comment and stuff".IsValidEmailAddress());
Assert.IsFalse("Abc.example.com".IsValidEmailAddress());
Assert.IsFalse("A@b@c@example.com".IsValidEmailAddress());
Assert.IsFalse("a\"b(c)d,e:f;g<h>i[j\\k]l@example.com".IsValidEmailAddress()); //a"b(c)d,e:f;g<h>i[j\k]l@example.com
Assert.IsFalse("just\"not\"right@example.com".IsValidEmailAddress()); //just"not"right@example.com
Assert.IsFalse("this is\"not\\allowed@example.com".IsValidEmailAddress()); //this is"not\allowed@example.com
Assert.IsFalse("this\\ still\\\"not\\\\allowed@example.com".IsValidEmailAddress());//this\ still\"not\\allowed@example.com
Assert.IsFalse("john..doe@example.com".IsValidEmailAddress());
Assert.IsFalse("john.doe@example..com".IsValidEmailAddress());
Assert.IsFalse(" joe@gmail.com".IsValidEmailAddress());
Assert.IsFalse("joe@gmail.com ".IsValidEmailAddress());
}
}
public static class ExtensionMethods
{
private const string ValidLocalPartChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&'*+-/=?^_`{|}~";
private const string ValidQuotedLocalPartChars = "(),:;<>@[]. ";
private const string ValidDomainPartChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-:";
private enum EmailParseMode
{
BeginLocal, Local, QuotedLocalEscape, QuotedLocal, QuotedLocalEnd, LocalSplit, LocalComment,
At,
Domain, DomainSplit, DomainComment, BracketedDomain, BracketedDomainEnd
};
public static bool IsValidEmailAddress(this string s)
{
bool valid = true;
bool hasLocal = false, hasDomain = false;
int commentStart = -1, commentEnd = -1;
var mode = EmailParseMode.BeginLocal;
for (int i = 0; i < s.Length; i++)
{
char c = s[i];
if (mode == EmailParseMode.BeginLocal || mode == EmailParseMode.LocalSplit)
{
if (c == '(') { mode = EmailParseMode.LocalComment; commentStart = i; commentEnd = -1; }
else if (c == '"') { mode = EmailParseMode.QuotedLocal; }
else if (ValidLocalPartChars.IndexOf(c) >= 0) { mode = EmailParseMode.Local; hasLocal = true; }
else { valid = false; break; }
}
else if (mode == EmailParseMode.LocalComment)
{
if (c == ')')
{
mode = EmailParseMode.Local; commentEnd = i;
// comments can only be at beginning and end of parts...
if (commentStart != 0 && ((commentEnd + 1) < s.Length) && s[commentEnd + 1] != '@') { valid = false; break; }
}
}
else if (mode == EmailParseMode.Local)
{
if (c == '.') mode = EmailParseMode.LocalSplit;
else if (c == '@') mode = EmailParseMode.At;
else if (c == '(') { mode = EmailParseMode.LocalComment; commentStart = i; commentEnd = -1; }
else if (ValidLocalPartChars.IndexOf(c) >= 0) { hasLocal = true; }
else { valid = false; break; }
}
else if (mode == EmailParseMode.QuotedLocal)
{
if (c == '"') { mode = EmailParseMode.QuotedLocalEnd; }
else if (c == '\\') { mode = EmailParseMode.QuotedLocalEscape; }
else if (ValidLocalPartChars.IndexOf(c) >= 0 || ValidQuotedLocalPartChars.IndexOf(c) >= 0) { hasLocal = true; }
else { valid = false; break; }
}
else if (mode == EmailParseMode.QuotedLocalEscape)
{
if (c == '"' || c == '\\') { mode = EmailParseMode.QuotedLocal; hasLocal = true; }
else { valid = false; break; }
}
else if (mode == EmailParseMode.QuotedLocalEnd)
{
if (c == '.') { mode = EmailParseMode.LocalSplit; }
else if (c == '@') mode = EmailParseMode.At;
else if (c == '(') { mode = EmailParseMode.LocalComment; commentStart = i; commentEnd = -1; }
else { valid = false; break; }
}
else if (mode == EmailParseMode.At)
{
if (c == '[') { mode = EmailParseMode.BracketedDomain; }
else if (c == '(') { mode = EmailParseMode.DomainComment; commentStart = i; commentEnd = -1; }
else if (ValidDomainPartChars.IndexOf(c) >= 0) { mode = EmailParseMode.Domain; hasDomain = true; }
else { valid = false; break; }
}
else if (mode == EmailParseMode.DomainComment)
{
if (c == ')')
{
mode = EmailParseMode.Domain;
commentEnd = i;
// comments can only be at beginning and end of parts...
if ((commentEnd + 1) != s.Length && (commentStart > 0) && s[commentStart - 1] != '@') { valid = false; break; }
}
}
else if (mode == EmailParseMode.DomainSplit)
{
if (ValidDomainPartChars.IndexOf(c) >= 0) { mode = EmailParseMode.Domain; hasDomain = true; }
else { valid = false; break; }
}
else if (mode == EmailParseMode.Domain)
{
if (c == '(') { mode = EmailParseMode.DomainComment; commentStart = i; commentEnd = -1; }
else if (c == '.') { mode = EmailParseMode.DomainSplit; }
else if (ValidDomainPartChars.IndexOf(c) >= 0) { hasDomain = true; }
else { valid = false; break; }
}
else if (mode == EmailParseMode.BracketedDomain)
{
if (c == ']') { mode = EmailParseMode.BracketedDomainEnd; }
else if (c == '.' || ValidDomainPartChars.IndexOf(c) >= 0) { hasDomain = true; }
else { valid = false; break; }
}
else if (mode == EmailParseMode.BracketedDomain)
{
if (c == '(') { mode = EmailParseMode.DomainComment; commentStart = i; commentEnd = -1; }
else { valid = false; break; }
}
}
bool unfinishedComment = (commentEnd == -1 && commentStart >= 0);
return hasLocal && hasDomain && valid && !unfinishedComment;
}
}
}
/// <summary>
/// Validates the email if it follows the valid email format
/// </summary>
/// <param name="emailAddress"></param>
/// <returns></returns>
public static bool EmailIsValid(string emailAddress)
{
//if string is not null and empty then check for email follow the format
return string.IsNullOrEmpty(emailAddress)?false : new Regex(@"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$", RegexOptions.IgnoreCase).IsMatch(emailAddress);
}
public static bool IsEmail(string strEmail)
{
Regex rgxEmail = new Regex(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
@"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
@".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
return rgxEmail.IsMatch(strEmail);
}
public bool IsValidEmail(string email)
{
try
{
var addr = new System.Net.Mail.MailAddress(email);
return addr.Address == email;
}
catch
{
return false;
}
}