validation电子邮件地址的C#代码

什么是最优雅的代码来validation一个string是一个有效的电子邮件地址?

那这个呢?

bool IsValidEmail(string email) { try { var addr = new System.Net.Mail.MailAddress(email); return addr.Address == email; } catch { return false; } } 

为了澄清,问题是询问一个特定的string是否是电子邮件地址的有效表示,而不是电子邮件地址是否是发送消息的有效目的地。 为此,唯一真正的方法是发送消息来确认。

请注意,电子邮件地址比您先假设的更容易。 这些都是完全有效的forms:

  • COG @轮
  • “绶橙”@ example.com
  • 123@$.xyz

对于大多数使用情况来说,错误的“无效”对于您的用户和未来的校样来说比错误的“有效”要糟糕得多。 这是一个曾经被接受的答案 (这个答案已经被删除)。 它有更多的细节和一些如何解决这个问题的其他想法。

提供完整性检查对于用户体验来说仍然是一个好主意。 假设电子邮件通过validation,然后您可以通过另一个validation程序,它可以查找一个已知的顶级域名,检查域的MXlogging,检查从常见域名(gmail.cmo),拼写错误等然后给用户一个机会说“是的,我的邮件服务器确实允许🌮🍳🎁作为电子邮件地址”。

至于使用exception处理的业务逻辑,我同意这是一个要避免的事情。 但这是便利和清晰可能超过教条的情况之一。

按照斯图亚特的评论,这个比较最后的地址与原始string,而不是总是返回true。 MailAddress尝试使用空格parsingstring到“显示名称”和“地址”部分,因此原始版本返回误报。

这是一个古老的问题,但是我发现的所有答案,包括最近的答案都与这个答案类似。 但是,在.Net 4.5 / MVC 4中,您可以通过添加来自System.ComponentModel.DataAnnotations的[EmailAddress]批注来添加电子邮件地址validation到表单,所以我想知道为什么我不能只使用内置的function。一般网。

这似乎工作,在我看来相当优雅:

 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; } } 

就我个人而言,我想说,你应该确保那里有一个@符号,可能有一个。 字符。 有很多正则expression式可以使用不同的正确性,但是我认为这些正则expression式中的大部分都不包含有效的电子邮件地址,或者让无效的电子邮件地址通过。 如果人们想要input一个虚假的电子邮件地址,他们会伪造一个。 如果您需要validation电子邮件地址是否合法,并且该人员正在控制该电子邮件地址,则您需要向他们发送一封带有特殊编码链接的电子邮件,以便确认其确实是真实地址。

我从菲尔从#1的答案,并创build了这个类。 像这样调用它: bool isValid = Validator.EmailIsValid(emailString);

这是class级:

 using System.Text.RegularExpressions; public static class Validator { static Regex ValidEmailRegex = CreateValidEmailRegex(); /// <summary> /// Taken from http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx /// </summary> /// <returns></returns> private static Regex CreateValidEmailRegex() { string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[az][az\.]*[az]$"; return new Regex(validEmailPattern, RegexOptions.IgnoreCase); } internal static bool EmailIsValid(string emailAddress) { bool isValid = ValidEmailRegex.IsMatch(emailAddress); return isValid; } } 

.net 4.5添加了System.ComponentModel.DataAnnotations.EmailAddressAttribute

您可以浏览EmailAddressAttribute的来源 ,这是它在内部使用的正则expression式:

 const string pattern = @"^((([az]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([az]|\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\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([az]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([az]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([az]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([az]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([az]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([az]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([az]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([az]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$"; 

我使用这个单线程的方法,为我做的工作 –

 using System.ComponentModel.DataAnnotations; public bool IsValidEmail(string source) { return new EmailAddressAttribute().IsValid(source); } 

我认为最好的方法如下:

  public static bool emailIsValid(string email) { string expresion; expresion = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*"; if (Regex.IsMatch(email, expresion)) { if (Regex.Replace(email, expresion, string.Empty).Length == 0) { return true; } else { return false; } } else { return false; } } 

你可以在一个普通的类中使用这个静态函数。

我发现这个正则expression式在检查@标记之外是一个很好的折衷,并接受奇怪的边界情况:

 ^[^@\s]+@[^@\s]+(\.[^@\s]+)+$ 

它至less会让你在@标记附近放置一些东西,并至less放一个正常的域名。

电子邮件地址validation并不像看起来那么简单。 实际上,仅仅使用正则expression式来validation电子邮件地址实际上是不可能的。

看看我的博客文章关于这个主题的讨论和使用FParsec的F#实现。 [/ shameless_plug]

说实话,在生产代码中,我所做的最好的是检查@符号。

我永远无法完全validation电子邮件。 你知道我是如何看它是否真的有效? 如果它发送。 如果没有,那很糟糕,如果有的话,生活是很好的。 这就是我需要知道的。

最优雅的方法是使用.Net的内置方法。

这些方法:

  • 经过尝试和testing。 这些方法在我自己的专业项目中使用。

  • 内部使用正则expression式,这是可靠和快速的。

  • 由微软为C#制作。 没有必要重新发明轮子。

  • 返回一个布尔结果。 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()); } 

另外,这个例子:

  • 由于单个string用于包含0,分号分隔的一个或多个电子邮件地址,所以超出了规范;
  • 清楚地演示如何使用EmailAddressAttribute对象的IsValid方法。

另一种方法是.Net版本低于4.5的用户

对于.Net 4.5不可用的情况,我使用以下解决scheme:

具体来说,我使用:

 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; } 

如果你真的和我的意思是真的想知道一个电子邮件地址是否有效…要求邮件交换器来certificate它,不需要正则expression式。 如果需要,我可以提供代码。

一般步骤如下:1.电子邮件地址是否有域名部分? (@> 0的索引)2.使用DNS查询询问域是否有邮件交换器3.打开tcp连接到邮件交换器4.使用smtp协议,使用电子邮件地址作为收件人5打开一条消息到服务器。parsing服务器的响应。 6.如果你做到这一点,就放弃信息,一切都好。

这是你可以想象的,非常昂贵的时间明智,依赖于smtp,但它确实有效。

这是我的答案 – 菲尔的解决scheme没有像“someone@q.com”这样的单字母域名。 信不信由你用=)(比如centurylink)。

菲尔的答案也将只与PCRE标准工作…所以C#将采取它,但JavaScript将要炸弹。 这对于JavaScript来说太复杂了。 所以你不能使用Phil的解决scheme来获得mvcvalidation属性。

这是我的正则expression式。 这将与MVCvalidation属性很好地工作。
– @之前的所有内容都被简化了,所以至lessjavascript会起作用。 只要交换服务器不给我一个5.1.3,我可以在这里放松validation。 – @之后的所有内容都是对单字母域进行修改的菲尔解决scheme。

 public const string EmailPattern = @"^\s*[\w\-\+_']+(\.[\w\-\+_']+)*\@[A-Za-z0-9]([\w\.-]*[A-Za-z0-9])?\.[A-Za-z][A-Za-z\.]*[A-Za-z]$"; 

对于build议使用system.net.mail MailMessage()的人来说,这是灵活的方法。 当然,C#会接受电子邮件,但是只要您尝试发送电子邮件,交换服务器就会popup5.1.3运行时错误。

一般来说,validation电子邮件地址的正则expression式不是一件容易的事情; 在撰写本文时,电子邮件地址的语法必须遵循相对较高的标准,并且在正则expression式中实现所有这些标准实际上是不可行的!

我强烈build议您尝试我们的EmailVerify.NET ,这是一个成熟的.NET库,可以根据当前的所有 IETF标准(RFC 1123,RFC 2821,RFC 2822,RFC 3696,RFC 4291,RFC 5321和RFC 5322)validation电子邮件地址。 ,testing相关的DNSlogging,检查目标邮箱是否可以接收邮件,甚至可以知道给定的地址是否是一次性的。

免责声明:我是该组件的首席开发人员。

检查电子邮件string是正确的格式或错误的格式由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"; } } 

/使用内部正则expression式创build“新的EmailAddressAttribute();” 组件在.Net4.5 >>>使用System.ComponentModel.DataAnnotations; //validation电子邮件地址……testing和工作。

 public bool IsEmail(string email) { if (String.IsNullOrEmpty(email)) { return false; } try { Regex _regex = new Regex("^((([az]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])" + "+(\\.([az]|\\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)))@((([az]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|" + "(([az]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([az]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([az]|\\d|" + "[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([az]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([az]|[\\u00A0-\\uD7FF\\uF900" + "-\\uFDCF\\uFDF0-\\uFFEF])([az]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([az]|[\\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

这里是你的问题的答案你检查。

 using System; using System.Globalization; using System.Text.RegularExpressions; public class RegexUtilities { public bool IsValidEmail(string strIn) { if (String.IsNullOrEmpty(strIn)) { return false; } // Use IdnMapping class to convert Unicode domain names. try { strIn = Regex.Replace(strIn, @"(@)(.+)$", this.DomainMapper, RegexOptions.None, TimeSpan.FromMilliseconds(200)); } catch (RegexMatchTimeoutException) { return false; } if (invalid) { return false; } // Return true if strIn is in valid e-mail format. try { return Regex.IsMatch(strIn, @"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))| [-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)); } catch (RegexMatchTimeoutException) { return false; } } private string DomainMapper(Match match) { // IdnMapping class with default property values. IdnMapping idn = new IdnMapping(); string domainName = match.Groups[2].Value; try { domainName = idn.GetAscii(domainName); } catch (ArgumentException) { invalid = true; } return match.Groups[1].Value + domainName; } } 
 private static bool IsValidEmail(string emailAddress) { const string validEmailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[az][az\.]*[az]$"; return new Regex(validEmailPattern, RegexOptions.IgnoreCase).IsMatch(emailAddress); } 

我把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; } 

识别emailid的简单方法是否有效。

 public static bool EmailIsValid(string email) { return Regex.IsMatch(email, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"); } 

C#中的正则expression式存在文化问题,而不是js。 所以我们需要在美国模式下使用正则expression式来进行邮件检查。 如果你不使用ECMAScript模式,你的语言特殊字符在正则expression式中就是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) 

我结束了使用这个正则expression式,因为它成功地validation了逗号,注释,Unicode字符和IP(v4)域地址。

有效的地址将是:

“”@ example.org

(comment)test@example.org

тест@example.org

ტესტი@ example.org

testing@ [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,}))$"; 
 For the simple email like goerge@xxx.com, below code is sufficient. public static bool ValidateEmail(string email) { System.Text.RegularExpressions.Regex emailRegex = new System.Text.RegularExpressions.Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$"); System.Text.RegularExpressions.Match emailMatch = emailRegex.Match(email); return emailMatch.Success; } 
  1. 在“尝试块”中发送validation邮件。
  2. 让用户打开电子邮件,然后点击validation电子邮件的链接是真实的。

在此过程成功完成之前,电子邮件被假定为无效。

有一段时间,我写了一个EmailAddressValidationAttribute ,它可以正确地validation表单中相对正常的电子邮件地址

 local-part@domain 

这是一个System.ComponentModel.DataAnnotations.ValidationAttribute ,所以用法很简单。

而且,通过挖掘所有的RFC和勘误,并组装所有需要正确列举所有规则的位是很乏味的 – 充其量! – 我在源代码的C#电子邮件地址validation问题的答案中发布了validation程序的源代码。

我的validation器并不是完美的想象力,尽pipe对于初学者来说,它没有任何内置的支持来发布客户端的JavaScriptvalidation,尽pipe这样做不会太困难。我上面的回答:

这是我写的validation属性。 它几乎validation每个“原始”电子邮件地址,即那些formslocal-part @ domain 。 It doesn't support any of the other, more…creative constructs that the RFCs allow (this list is not comprehensive by any means):

  • comments (eg, jsmith@whizbang.com (work) )
  • quoted strings (escaped text, to allow characters not allowed in an atom)
  • domain literals (eg foo@[123.45.67.012] )
  • bang-paths (aka source routing)
  • angle addresses (eg John Smith <jsmith@whizbang.com> )
  • folding whitespace
  • double-byte characters in either local-part or domain (7-bit ASCII only).
  • 等等

It should accept almost any email address that can be expressed thusly

  • foo.bar@bazbat.com

without requiring the use of quotes ( " ), angle brackets ('<>') or square brackets ( [] ).

No attempt is made to validate that the rightmost dns label in the domain is a valid TLD (top-level domain). That is because the list of TLDs is far larger now than the "big 6" (.com, .edu, .gov, .mil, .net, .org) plus 2-letter ISO country codes. ICANN actually updates the TLD list daily , though I suspect that the list doesn't actually change daily. Further, [ICANN just approved a big expansion of the generic TLD namespace][2]). And some email addresses don't have what you'd recognize as a TLD (did you know that postmaster@. is theoretically valid and mailable? Mail to that address should get delivered to the postmaster of the DNS root zone.)

Extending the regular expression to support domain literals shouldn't be too difficult.

I created an email address validation routine based on Wikipedia's documented rules and sample addresses. For those that don't mind looking at a little more code, here you go. Honestly, I had no idea how many crazy rules there were in the email address specification. I don't fully validate the hostname or ipaddress, but it still passes all of the test cases on wikipedia.

 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; } } } 

A simple one without using Regex (which I don't like for its poor readability):

 bool IsValidEmail(string email) { string emailTrimed = email.Trim(); if (!string.IsNullOrEmpty(emailTrimed)) { bool hasWhitespace = emailTrimed.Contains(" "); int indexOfAtSign = emailTrimed.LastIndexOf('@'); if (indexOfAtSign > 0 && !hasWhitespace) { string afterAtSign = emailTrimed.Substring(indexOfAtSign + 1); int indexOfDotAfterAtSign = afterAtSign.LastIndexOf('.'); if (indexOfDotAfterAtSign > 0 && afterAtSign.Substring(indexOfDotAfterAtSign).Length > 1) return true; } } return false; } 

例子:

  • IsValidEmail("@b.com") // false
  • IsValidEmail("a@.com") // false
  • IsValidEmail("a@bcom") // false
  • IsValidEmail("ab@com") // false
  • IsValidEmail("a@b.") // false
  • IsValidEmail("ab@c.com") // false
  • IsValidEmail("a@b c.com") // false
  • IsValidEmail("a@b.com") // true
  • IsValidEmail("a@bccom") // true
  • IsValidEmail("a+b@c.com") // true
  • IsValidEmail("a@123.45.67.89") // true

It is meant to be simple and therefore it doesn't deal with rare cases like emails with bracketed domains that contain spaces (typically allowed), emails with IPv6 addresses, etc.

  /// <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]\.[az][az\.]*[az]$", RegexOptions.IgnoreCase).IsMatch(emailAddress); } 

This may be the best way for the email validation for your textbox.

 string pattern = null; pattern = "^([0-9a-zA-Z]([-\\.\\w]*[0-9a-zA-Z])*@([0-9a-zA-Z][-\\w]*[0-9a-zA-Z]\\.)+[a-zA-Z]{2,9})$"; if (Regex.IsMatch("txtemail.Text", pattern)) { MessageBox.Show ("Valid Email address "); } else { MessageBox.Show("Invalid Email Email"); } 

Just include in any function where you want.