C# code to validate email address
验证字符串是否为有效电子邮件地址最优雅的代码是什么?
这个怎么样?
1 2 3 4 5 6 7 8 9 10 | bool IsValidEmail(string email) { try { var addr = new System.Net.Mail.MailAddress(email); return addr.Address == email; } catch { return false; } } |
为了澄清这一点,问题在于特定的字符串是否是电子邮件地址的有效表示,而不是电子邮件地址是否是发送邮件的有效目的地。为此,唯一真正的方法是发送消息确认。
请注意,电子邮件地址比您最初想象的要宽容得多。这些都是完全有效的形式:
- 齿轮轮
- "齿轮橙色"@example.com
- 123 @ $ XYZ
对于大多数用例,错误的"无效"对您的用户和将来的校对比错误的"有效"更糟糕。这里有一篇文章曾经是这个问题的公认答案(这个答案已经被删除)。关于如何解决这个问题,它有更多的细节和其他一些想法。
对于用户体验来说,提供健全性检查仍然是一个好主意。假设电子邮件地址有效,您可以查找已知的顶级域、检查域中的MX记录、检查常见域名(gmail.cmo)的拼写错误等。然后给出警告,让用户有机会说"是,我的邮件服务器真的允许吗?"???????作为电子邮件地址。"
至于在业务逻辑中使用异常处理,我同意这是一件需要避免的事情。但这是其中一种情况,即便利性和清晰性可能超过教条。
此外,如果您对电子邮件地址做了其他操作,可能需要将其转换为邮件地址。即使您不使用这个精确的函数,您可能也希望使用相同的模式。您还可以通过捕获不同的异常来检查特定类型的失败:空、空或无效格式。
根据斯图尔特的评论,这会将最终地址与原始字符串进行比较,而不是总是返回true。mailaddress试图将带有空格的字符串解析为"显示名称"和"地址"部分,因此原始版本返回了误报。
——进一步阅读---
system.net.mail.mailaddress文档
解释有效电子邮件地址的组成
这是一个古老的问题,但我在上面找到的所有答案,包括最近的答案,都与这个问题的答案类似。但是,在.NET 4.5/MVC 4中,您可以通过添加System.ComponentModel.DataAnnotations中的[emailAddress]注释来向表单添加电子邮件地址验证,因此我想知道为什么不能仅使用.NET中的内置功能。
这似乎奏效,在我看来相当优雅:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | using System.ComponentModel.DataAnnotations; class ValidateSomeEmails { static void Main(string[] args) { var foo = new EmailAddressAttribute(); bool bar; bar = foo.IsValid("[email protected]"); //true bar = foo.IsValid("[email protected]"); //true bar = foo.IsValid("[email protected]"); //true bar = foo.IsValid("[email protected]"); //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("[email protected]")) bar = true; } } |
我用这种单一的线性方法为我工作-
1 2 3 4 5 | using System.ComponentModel.DataAnnotations; public bool IsValidEmail(string source) { return new EmailAddressAttribute().IsValid(source); } |
根据评论,如果EDOCX1(电子邮件地址)为空,这将"失败"。
1 | public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address); |
.NET 4.5添加了system.componentModel.dataAnnotations.emailAddressAttribute
您可以浏览emailAddressAttribute的源,这是它在内部使用的regex:
1 | const string pattern = @"^((([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\uFDF0-\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-\uFFEF])))\.?$"; |
我从1那里得到了菲尔的答案,并创建了这个课程。这样称呼:
这是课程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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 = @"^(?!\.)(""([^"" \\]|\\["" \\])*""|" + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$"; return new Regex(validEmailPattern, RegexOptions.IgnoreCase); } internal static bool EmailIsValid(string emailAddress) { bool isValid = ValidEmailRegex.IsMatch(emailAddress); return isValid; } } |
就我个人而言,我会说你应该确保里面有一个@符号,可能有一个。性格。有很多正则表达式可以使用不同的正确性,但我认为其中大多数都会遗漏有效的电子邮件地址,或者让无效的电子邮件地址通过。如果人们想输入假电子邮件地址,他们会输入假电子邮件地址。如果您需要验证电子邮件地址是否合法,以及该人是否控制该电子邮件地址,那么您需要向他们发送一封带有特殊编码链接的电子邮件,以便他们能够验证该地址是否为真实地址。
我认为最好的办法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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; } } |
您可以在常规类中使用这个静态函数。
最优雅的方法是使用.NET的内置方法。
这些方法:
经过测试。这些方法在我自己的专业项目中使用。
在内部使用可靠、快速的正则表达式。
由微软为C制造。没有必要重新发明轮子。
返回bool结果。如果为真,则表示电子邮件有效。
对于.NET 4.5和更大的用户
将此引用添加到项目中:
System.ComponentModel.DataAnnotations
现在您可以使用以下代码:
1 |
使用实例
下面是一些声明的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | 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; } |
和代码演示他们在行动:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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(" " + InvalidEmail); } MessageBox.Show(sb.ToString()); } |
此外,此示例:
- 扩展到规范之外,因为单个字符串用于包含由分号
; 指定的0、一个或多个电子邮件地址。 - 清楚地演示了如何使用emailAddressAttribute对象的isValid方法。
或者,对于.NET版本低于4.5的用户
对于.NET 4.5不可用的情况,我使用以下解决方案:
具体来说,我使用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 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; } |
短而准确的代码
1 2 3 4 5 6 7 8 9 10 | public static bool IsValidEmail(this string email) { string pattern = @"^(?!\.)(""([^"" \\]|\\["" \\])*""|" + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$"; var regex = new Regex(pattern, RegexOptions.IgnoreCase); return regex.IsMatch(email); } |
老实说,在生产代码中,我所做的最好的工作是检查
我从来没有在一个地方完全验证电子邮件。你知道我怎么看它是否真的有效吗?如果它被发送了。如果没有,那是不好的,如果是这样的话,生活是美好的。这就是我所需要知道的。
我发现这个正则表达式是一个很好的折衷方法,在检查一些不仅仅是"标记"的东西,并接受奇怪的边缘情况:
1 | ^[^@\s]+@[^@\s]+(\.[^@\s]+)+$ |
它至少会让你在@标记周围放置一些东西,并且至少放置一个看起来正常的域。
电子邮件地址验证并不像看上去那么简单。实际上,理论上不可能只用正则表达式来完全验证电子邮件地址。
查看我关于它的博客文章,了解关于这个主题的讨论以及使用fparsec实现f。/无耻的插头]
这是我的答案——对于"[email protected]"这样的单字母域名,Phil的解决方案失败了。信不信由你,那是用的=)(比如说去世纪银行)。
菲尔的答案也只适用于PCRE标准……所以C会接受它,但javascript会爆炸。对于javascript来说太复杂了。所以您不能将Phil的解决方案用于MVC验证属性。
这是我的瑞格鞋。它可以很好地与MVC验证属性配合使用。-@之前的一切都被简化了,这样至少javascript可以工作。只要Exchange服务器没有给我5.1.3,我可以在这里放松验证。-@之后的所有内容都是针对单字母域修改的Phil解决方案。
1 2 | 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]$"; |
对于建议使用system.net.mail mailmessage()的人来说,这是一种灵活的方法。当然,C会接受这封邮件,但是一旦你尝试发送这封邮件,Exchange Server就会弹出5.1.3运行时错误消息。
如果你真的和我的意思是真的想知道一个电子邮件地址是否有效……请邮件交换器证明它,不需要regex。如果需要,我可以提供代码。
一般步骤如下:1。电子邮件地址是否包含域名部分?(索引@>0)2。使用DNS查询询问域是否有邮件交换器三。打开到邮件交换器的TCP连接4。使用SMTP协议,使用电子邮件地址作为收件人打开一封邮件到服务器5。分析服务器的响应。6。如果你做到了这一点,就不要再写了,一切都很好。
这是你可以想象的,非常昂贵的时间和依赖于SMTP,但它确实有效。
通过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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"; } } |
"Cogwheel"中最被投票的答案是最佳答案,但是我已经尝试实现EDCOX1×11的字符串方法,所以它将把所有的用户空白从字符串开始到结束。检查代码波纹管为完整的例子-
1 2 3 4 5 6 7 8 9 10 11 12 13 | bool IsValidEmail(string email) { try { email = email.Trim(); var addr = new System.Net.Mail.MailAddress(email); return addr.Address == email; } catch { return false; } } |
一般来说,验证电子邮件地址的正则表达式不是一件容易想到的事情;在撰写本文时,电子邮件地址的语法必须遵循相对较高的标准,并且在正则表达式中实现所有这些标准实际上是不可行的!
我强烈建议您尝试我们的emailverify.net,它是一个成熟的.NET库,可以按照当前IETF标准(RFC 1123、RFC 2821、RFC 2822、RFC 3696、RFC 4291、RFC 5321和RFC 5322)验证电子邮件地址,测试相关的DNS记录,检查目标邮箱是否可以接受消息,甚至可以判断给定地址是否为DI。是否可分割。
免责声明:我是这个组件的主要开发人员。
这里有很多很强的答案。但是,我建议我们退后一步。@ ggEnter回答问题HTPS://StaskOfFult.COM/A/137644/88267。然而,如果大量验证的电子邮件地址无效,则在批量验证方案中可能会很昂贵。我建议我们在进入他的试块之前使用一点逻辑。我知道下面的代码可以使用ReGEX编写,但这对于新开发人员来说可能是昂贵的。这是我的两倍价值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public static bool IsEmail(this string input) { if (string.IsNullOrWhiteSpace(input)) return false; // MUST CONTAIN ONE AND ONLY ONE @ var atCount = input.Count(c => c == '@'); if (atCount != 1) return false; // MUST CONTAIN PERIOD if (!input.Contains(".")) return false; // @ MUST OCCUR BEFORE LAST PERIOD var indexOfAt = input.IndexOf("@", StringComparison.Ordinal); var lastIndexOfPeriod = input.LastIndexOf(".", StringComparison.Ordinal); var atBeforeLastPeriod = lastIndexOfPeriod > indexOfAt; if (!atBeforeLastPeriod) return false; // CODE FROM COGWHEEL'S ANSWER: https://stackoverflow.com/a/1374644/388267 try { var addr = new System.Net.Mail.MailAddress(input); return addr.Address == input; } catch { return false; } } |
1 2 3 4 5 6 7 8 | 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 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; } } |
/使用用于使用System.ComponentModel.DataAnnotations在.net4.5>>中创建"new emailAddressAttribute();"组件的内部regex;//验证电子邮件地址……已测试并正常工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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
C中的regex存在文化问题,而不是JS。所以我们需要在美国模式下使用regex进行电子邮件检查。如果您不使用ecmascript模式,您的语言特殊字符在a-z中与regex一起使用。
1 | 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) |
对@cogwheel答案做了一点修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public static bool IsValidEmail(this string email) { // skip the exception & return early if possible if (email.IndexOf("@") <= 0) return false; try { var address = new MailAddress(email); return address.Address == email; } catch { return false; } } |
基于@cogwheel的答案,我想共享一个适用于ssis和"脚本组件"的修改过的解决方案:
将此代码放在正确的方法中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public override void Input0_ProcessInputRow(Input0Buffer Row) { string email = Row.fieldName; try { System.Net.Mail.MailAddress addr = new System.Net.Mail.MailAddress(email); Row.fieldName= addr.Address.ToString(); } catch { Row.fieldName ="WRONGADDRESS"; } } |
然后,您可以使用条件拆分来筛选出所有无效的记录或您希望执行的任何操作。
如果您使用FluentValidation,您可以编写如下简单的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public cass User { public string Email { get; set; } } public class UserValidator : AbstractValidator<User> { public UserValidator() { RuleFor(x => x.Email).EmailAddress().WithMessage("The text entered is not a valid email address."); } } // Validates an user. var validationResult = new UserValidator().Validate(new User { Email ="a?flkdj" }); // This will return false, since the user email is not valid. bool userIsValid = validationResult.IsValid; |
我如此简明扼要地阐述了Poyson 1的答案:
1 2 3 4 5 6 | 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); } |
我最终使用了这个regex,因为它成功地验证了逗号、注释、Unicode字符和IP(v4)域地址。
有效地址为:
""@example.org
(comment)[email protected]
тест@example.org
test@[192.168.1.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,}))$"; |
1 2 3 4 5 6 7 8 9 10 | private static bool IsValidEmail(string emailAddress) { const string validEmailPattern = @"^(?!\.)(""([^"" \\]|\\["" \\])*""|" + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$"; return new Regex(validEmailPattern, RegexOptions.IgnoreCase).IsMatch(emailAddress); } |
识别emailid的简单方法是否有效。
1 2 3 4 | 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})(\]?)$"); } |
我编写了一个函数来检查电子邮件是否有效。在大多数情况下,它对我来说似乎很有效。
结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 |
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 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(@"^[[email protected]]*$"); 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; } |
不使用regex的简单方法(我不喜欢它的可读性差):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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("[email protected]") // false IsValidEmail("a@bcom") // false IsValidEmail("a.b@com") // false IsValidEmail("a@b.") // false IsValidEmail("a [email protected]") // false IsValidEmail("a@b c.com") // false IsValidEmail("[email protected]") // true IsValidEmail("[email protected]") // true IsValidEmail("[email protected]") // true IsValidEmail("[email protected]") // true
它的目的是简单的,因此它不处理罕见的情况,如带括号的域包含空格(通常允许)、带ipv6地址的电子邮件等。
前一段时间,我写了一个
1 | local-part@domain |
它是一个
而且,由于挖掘了所有的RFC和勘误表,并组装了正确枚举所有规则所需的所有位,因此……最多是冗长的&mdash;!&mdash;我将验证程序的源代码发布在我对源代码的问题C电子邮件地址验证的答案中。
我的验证器并不是想象中的完美,尽管只是一个初学者,但它没有任何内置的支持来发出客户端的javascript验证,尽管添加它并不太困难。从我上面的回答来看:
Here's the validation attribute I wrote. It validates pretty much every"raw" email
address, that is those of the form local-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 (e.g.,
[email protected] (work) )- quoted strings (escaped text, to allow characters not allowed in an atom)
- domain literals (e.g.
foo@[123.45.67.012] )- bang-paths (aka source routing)
- angle addresses (e.g.
John Smith )- folding whitespace
- double-byte characters in either local-part or domain (7-bit ASCII only).
- etc.
It should accept almost any email address that can be expressed thusly
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 thatpostmaster@. 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.
我根据维基百科记录的规则和示例地址创建了一个电子邮件地址验证程序。对于那些不介意再看一点代码的人,给你。老实说,我不知道在电子邮件地址规范中有多少疯狂的规则。我没有完全验证主机名或IP地址,但它仍然通过了维基百科上的所有测试用例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | using Microsoft.VisualStudio.TestTools.UnitTesting; namespace EmailValidateUnitTests { [TestClass] public class EmailValidationUnitTests { [TestMethod] public void TestEmailValidate() { // Positive Assertions Assert.IsTrue("[email protected]".IsValidEmailAddress()); Assert.IsTrue("[email protected]".IsValidEmailAddress()); Assert.IsTrue("[email protected]".IsValidEmailAddress()); Assert.IsTrue("[email protected]".IsValidEmailAddress()); Assert.IsTrue(""much.more unusual"@example.com".IsValidEmailAddress()); Assert.IsTrue(""very.unusual.@.unusual.com"@example.com".IsValidEmailAddress()); //"[email protected]"@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("#!$%&'*+-/=?^_`{}|[email protected]".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("[email protected]".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)[email protected]".IsValidEmailAddress()); Assert.IsTrue("joe(comment and stuff)@gmail.com".IsValidEmailAddress()); Assert.IsTrue("joe@(comment and stuff)gmail.com".IsValidEmailAddress()); Assert.IsTrue("[email protected](comment and stuff)".IsValidEmailAddress()); // Failure Assertions Assert.IsFalse("joe(fail me)[email protected]".IsValidEmailAddress()); Assert.IsFalse("joesmith@gma(fail me)il.com".IsValidEmailAddress()); Assert.IsFalse("[email protected](comment and stuff".IsValidEmailAddress()); Assert.IsFalse("Abc.example.com".IsValidEmailAddress()); Assert.IsFalse("A@b@[email protected]".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"[email protected]".IsValidEmailAddress()); //just"not"[email protected] 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("[email protected]".IsValidEmailAddress()); Assert.IsFalse("[email protected]".IsValidEmailAddress()); Assert.IsFalse(" [email protected]".IsValidEmailAddress()); Assert.IsFalse("[email protected]".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; } } } |
在这个过程成功完成之前,电子邮件被认为是无效的。
1 2 3 4 5 6 7 8 9 10 11 12 | /// <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(@"^(?!\.)(""([^"" \\]|\\["" \\])*""|([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$", RegexOptions.IgnoreCase).IsMatch(emailAddress); } |
这可能是对文本框进行电子邮件验证的最佳方法。
1 2 3 4 5 6 7 8 9 10 11 | 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"); } |
只要在你想要的任何函数中包含。
1 2 3 4 5 6 7 | 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); } |
1 2 3 4 5 6 7 8 9 10 11 12 | public bool IsValidEmail(string email) { try { var addr = new System.Net.Mail.MailAddress(email); return addr.Address == email; } catch { return false; } } |