用于验证电子邮件地址的C#代码

leo*_*ora 419 c# email email-validation

验证字符串是否为有效电子邮件地址的最优雅代码是什么?

Cog*_*eel 713

那这个呢?

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

为了澄清,问题是询问特定字符串是否是电子邮件地址的有效表示,而不是电子邮件地址是否是发送消息的有效目的地.为此,唯一真正的方法是发送消息进行确认.

请注意,电子邮件地址比您可能首先假设的更宽容.这些都是完全有效的形式:

  • COG @轮
  • "co the the orange"@ example.com
  • 123@$.xyz

对于大多数用例,假的"无效"对于您的用户和将来的校对来说比虚假的"有效"更糟糕.这里有一个曾经是公认的答案的文章对这个问题(这个问题的答案已经被删除).它有更多的细节和一些其他如何解决问题的想法.

提供健全性检查仍然是用户体验的好主意.假设电子邮件地址有效,您可以查找已知的顶级域名,检查域名中的MX记录,检查来自常用域名(gmail.cmo)的拼写错误等.然后向用户显示警告有机会说"是的,我的邮件服务器确实允许作为电子邮件地址."


至于对业务逻辑使用异常处理,我同意这是一个需要避免的事情.但这是方便和清晰度可能超过教条的情况之一.

此外,如果您使用电子邮件地址执行任何其他操作,则可能需要将其转换为MailAddress.即使您不使用此功能,您也可能希望使用相同的模式.您还可以通过捕获不同的异常来检查特定类型的故障:null,empty或invalid format.


Per Stuart的评论,这将最终地址与原始字符串进行比较,而不是始终返回true.MailAddress尝试将带有空格的字符串解析为"显示名称"和"地址"部分,因此原始版本返回误报.


---进一步阅读---

System.Net.Mail.MailAddress的文档

有关构成有效电子邮件地址的说明

  • +1:如果您使用`System.Net.Mail`类发送邮件,这是最佳答案,如果您使用的是.NET,则可能就是这样.我们决定使用这种类型的验证只是因为我们没有必要接受我们无法发送邮件的电子邮件地址 - 即使是有效的电子邮件地址. (51认同)
  • 我不推荐.它返回true:`IsValidEmail("这是无效的@ email $ com");` (23认同)
  • 实际上,这不是不正确的.a @ a是有效的电子邮件地址.请参阅http://haacked.com/archive/2007/08/21/i-knew-how-to-validate-an-email-address-until-i.aspx事实上,如果您使用此方法确实会返回不正确的结果带引号的地址. (22认同)
  • 我喜欢这个; 我没有强迫比实际规格更具限制性.假阴性比假阳性更糟糕("你的意思是我的电子邮件*无效?*") (17认同)
  • 很多问题似乎都是因为MailAddress也尝试解析DisplayName,因此"single space@domain.com"解析为DisplayName"single"和Address"space@domain.com".解决此问题的方法是:return(addr.Address == email); (13认同)
  • 我认为它不起作用.我只是简单地用@ a尝试了它,它返回true.那错了. (12认同)
  • 这是一个很好的解决方案; 为什么重新发明轮子以确定有效的电子邮件地址是什么时候你可以让.NET为你做这件事?虽然我现在不太信任微软,但我很乐意让他们决定什么是有效的,什么不是.如果这不符合您的需求,请不要在评论中哭泣,只需使用RegEx即可.事实仍然是,这可能符合Google"验证.NET中的电子邮件地址"的90%的人的需求. (10认同)
  • 如果您阅读规范,那显然不是错误的.问题是关于特定字符串是否是电子邮件地址的有效表示,而不是该电子邮件地址是否可能存在于某个服务器上. (8认同)
  • @Kakashi:看看我上面发布的链接.如果您通过检查RFC进行跟进,您将看到"DNS名称中允许使用任何字符或位组合(作为八位字节).但是,大多数应用程序都需要一个首选表单." 换句话说,只有使该地址无效的惯例.您始终可以使用此代码创建的MailAddress对象,并进一步验证主机部分. (7认同)
  • 安全性评论:这是一种众所周知的类似DOS的攻击,其中一个巨大的电子邮件表达提供给服务器,并且在该表达式上运行电子邮件验证时它永远变得忙碌.在运行'IsEmailValid'方法之前,请务必检查电子邮件字符串长度! (6认同)
  • 我不喜欢这个解决方案的唯一原因是它依赖于异常处理,这在我的书中是缓慢而不好的做法.对于这个特定的解决方案,有没有办法解决这个问题?我找不到一个. (5认同)
  • -1除了使用`Exception`进行验证之外,`System.Net.Mail.MailAddress`批准了太多的字符串组合,这些字符串组合在现实中会失败并且根据RFC规范也是错误的,例如`unescaped white space @ fake $ com`. (5认同)
  • @DougS现实世界在不断变化.您无法预测未来将使用您的代码的位置(可能是在使用公共互联网上不存在的内部域的环境中?),未来将存在哪些TLD,哪种地址是电子邮件提供商支持,并且不断提供支持.对于一般适用性,你在这样的函数中做出的假设越少越好,imo.作为对提出的问题的回答,我没有看到这是错误的.提问者没有具体说明你所做的任何假设,并且接受了所有给定答案中最迂腐的. (5认同)
  • @Andreas我认为你对"验证"在这个问题的上下文中意味着什么有不同的看法.仅仅因为字符串是有效的电子邮件地址,并不意味着电子邮件地址实际存在于某个服务器上.如果那不是您的意思,那么我建议您阅读上面的所有评论以及在接受的答案中链接的文章. (4认同)
  • @RezaRahmati - 这是正确的.电子邮件地址解析为可在本地网络上访问但不属于域的计算机是完全可以接受的.我有一个简单称为"邮件"的测试VM,我可以发送到@ mail的地址,就像我应该的那样.这种方法的要点是,如果您要通过SmptClient实例发送,您将使用MailAddress.这只是提供了一种主动捕获MailAddress在发送之前最终会拒绝的地址的方法.这里的大部分(不是全部)评论实际上都在RFC中解决. (4认同)
  • 我对此代码的第一次测试,IsValidEmail("xxx@u*.com")= true,这显然是错误的.更不用说使用控制流的例外:( (3认同)
  • 我很困惑为什么每个人都说`MailAddress`说得对.``test email@hotmail.com"`回来是有效的,我在规范中找不到任何东西,说你可以在名字的本地部分有一个未转义的空格字符. (3认同)
  • MailAddress可能会从RFC中弄错,但大多数评论都是关于人们认为错误的事情.无论哪种方式,如果您在.Net环境中,这是确保您拥有System.Net.Mail可接受的地址的最佳方法. (3认同)
  • -1我必须同意其他人的意见,虽然这个答案在技术上是正确的,根据RFC规范(实际上它根据我上面的2条评论甚至没有这样做),但它对原始问题的精神是不正确的因为这个答案认为有效的许多地址实际上会失败.标准的RegEx更适合回答原始问题的精神. (3认同)
  • 电子邮件地址的最大长度为254。请参阅:https://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address (3认同)
  • @GuneyOzsan这不是2.0的错,而是Unity的.Unity的C#环境与实际的.Net非常不同 (3认同)
  • @TK-421:我纠正了。描述邮件地址的 RFC“不”引用 DNS 规范。它对地址的域部分有自己的定义,并且似乎不允许使用句点。 (3认同)
  • 这个没有验证,没有用。 (2认同)
  • @Cogwheel根据应用程序的不同,这不是一个错误的答案。但是,对于大多数应用程序而言,负面影响远大于优雅,因此最好使用诸如RegEx之类的其他解决方案。 (2认同)
  • 好.只要我们清楚你的downvote完全是主观的,那么...... (2认同)
  • 我已阅读所有评论,发现许多用户甚至没有测试或阅读规格就拒绝了您的回答。我检查了地址中的空格,它不接受电子邮件地址中的空格,但是有很多评论抱怨评论中的空格。我会推荐使用它。但唯一的缺点是我们对它背后的代码一无所知,因此如果选择使用 RegEx 模式会更明智一些。我已经将您的答案的许多结果与 Haack 提出的 RegEx 的结果进行了比较。它们在许多情况下具有相同的性能 (2认同)
  • @AdamV我的2分:如果您计划每秒检查数百万个电子邮件地址,那么您的评论是完全有效的。而且我敢肯定,确实有人会想要这样做。但是,在大多数情况下,此代码将用于检查用户在网站上输入的电子邮件,我相信即使是大型网站,每秒也只会检查几封电子邮件。同样,电子邮件地址的目的是发送电子邮件,这可能比引发异常慢一百万倍。底线是:不要过早地进行优化,除非(据说)更快的代码是如此简单,不容易出错且可维护。 (2认同)
  • 此方法显示“test@test.com”。是一个有效的电子邮件。电子邮件不能以点结尾。 (2认同)

imj*_*osh 220

这是一个古老的问题,但我在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;    
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`EmailAddressAttribute`比`System.Net.Mail.MailAddress`更不宽容 - 例如,`MailAddress`接受TLD的地址.如果您需要尽可能宽容,请记住一些事情. (13认同)
  • @hofnarwillie:它是在主体,但评论详述.如果您的目标是不激怒您的用户,那么您的验证不应该比规范更具限制性.真正验证电子邮件是否有效的唯一方法是发送测试邮件. (6认同)
  • @Cogwheel:如果答案在评论的某处,那么它应该被添加到答案的主体中. (5认同)
  • 正如 @Hoffs 所指出的,当前的实现非常不同。现在只检查“@”字符!**真的很可怕**像“asd@asd.com”或1=1这样的文本现在被认为是有效的。我认为需要添加 NetCore 实现的 **非常明显** 免责声明...... (5认同)
  • 很酷,虽然令人失望的是MS不能同意[他们自己的文档](http://msdn.microsoft.com/en-us/library/01escwtf(v = vs.110).aspx).这拒绝了js@proseware.com9 (4认同)
  • @hofnarwillie:你没看过评论,是吗? (4认同)
  • 请注意``foo.IsValid(null);`返回`true`. (4认同)
  • 如果您在视图模型中使用[EmailAddress](就像我一样),这是一种灵活的方法,可确保您在代码中使用相同的验证逻辑 - 无论好坏. (3认同)
  • @hofnarwillie:是的,因为那是一个有效的电子邮件地址.请参阅我的回答中的链接和评论. (3认同)
  • 对我来说,这一行返回 true,这是不正确的 `var result = new EmailAddressAttribute().IsValid("govinda@gmailcom");` (3认同)
  • @Cogwheel,谢谢,但是您的解决方案证明了该电子邮件地址根据规范是有效的,而不是该电子邮件地址在生产环境中是否将是有效的电子邮件-因为没有人会使用此电子邮件地址:`。 ............ @ t` 我并不是在理论上进行验证,而是要确保我的用户使用有效的电子邮件地址进行注册。从那以后,我决定,唯一的方法就是发送确认电子邮件。 (2认同)
  • @Cogwheel:全部36个?没有。 (2认同)
  • @Cogwheel:好主意。谢谢,我现在决定发送确认电子邮件。 (2认同)
  • @Casey如果查看属性的参考源(https://github.com/Microsoft/referencesource/blob/master/System.ComponentModel.DataAnnotations/DataAnnotations/EmailAddressAttribute.cs),它会显示_“此属性提供服务器电子邮件验证等效于jquery validate,因此共享相同的正则表达式“ _”。因此,我认为应该责怪jQuery电子邮件验证(我认为https://jqueryvalidation.org/email-method/)。 (2认同)
  • @OhadSchneider仅包含TLD的电子邮件地址,例如_example @ com_ (2认同)
  • 另请注意,.Net Core 实现似乎与 .Net Framework 截然不同且简单得多:https://source.dot.net/#System.ComponentModel.Annotations/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs,c3ae85dfd8a9f58c (2认同)

Man*_*ora 51

我使用这种单线程方法为我工作 -

using System.ComponentModel.DataAnnotations;
public bool IsValidEmail(string source)
{
    return new EmailAddressAttribute().IsValid(source);
}
Run Code Online (Sandbox Code Playgroud)

根据评论,如果source(电子邮件地址)为空,这将"失败" .

public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
Run Code Online (Sandbox Code Playgroud)

  • 甚至更好:`public static bool IsValidEmailAddress(this string address)=> address!= null && new EmailAddressAttribute().IsValid(address);` (5认同)
  • 我认为这个扩展方法不应该为空字符串默默返回“false”。这就是为什么我提出(更好更好)++ 版本:`public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());`。我现在要去找到更好更好版本主义者的改革宗教会。 (3认同)
  • 一个更好的版本:`public static Boolean IsValidMailAddress(this String pThis)=> pThis == null?false:new EmailAddressAttribute().IsValid(pThis);` (2认同)

Cha*_*ant 41

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

您可以浏览EmailAddressAttribute的源代码,这是它在内部使用的Regex:

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])))\.?$";
Run Code Online (Sandbox Code Playgroud)

  • @BZ是的.为什么你认为不是? (14认同)
  • 不幸的是,EmaillAddressAttribute允许Ñ,这不是电子邮件的有效字符 (2认同)
  • 这是可行的,但不要忘记`RegexOptions.IgnoreCase`,因为此模式不允许显式使用大写字母! (2认同)
  • 请注意,Regex 是经过深思熟虑的:_“此属性提供与 jquery validate 等效的服务器端电子邮件验证,因此共享相同的正则表达式”。_ (2认同)

Dav*_*ith 37

我从#1那里得到了Phil的答案并创建了这个课程.像这样称呼它:bool isValid = Validator.EmailIsValid(emailString);

这是班级:

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]\.[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;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 只是一个小的,但我会使用:return(!string.IsNullOrEmpty(emailAddress))&& ValidEmailRegex.IsMatch(emailAddress); (5认同)

Kib*_*bee 29

就个人而言,我会说你应该确保那里有一个@符号,可能还有一个.字符.有许多正则表达式可以使用不同的正确性,但我认为其中大多数都会遗漏有效的电子邮件地址,或者通过无效的电子邮件地址.如果人们想要输入一个虚假的电子邮件地址,他们会放入一个虚假的电子邮件地址.如果您需要验证电子邮件地址是否合法,并且该人员已控制该电子邮件地址,那么您需要向他们发送带有特殊编码链接的电子邮件,以便他们可以验证它确实是真实地址.

  • 如果你使用预备语句,bobby table的电子邮件地址有什么问题.我们讨论的是有效的电子邮件地址,而不是与构成有效电子邮件地址无关的其他内容,例如如何正确执行SQL查询以便不会出现SQL注入问题. (31认同)
  • 这是邮件系统担心的问题.我不会仅仅因为它可能是某些其他系统的安全问题而拒绝完全有效的电子邮件地址.如果您的所有电子邮件服务器需要的格式错误的电子邮件地址都会导致安全问题,您应该切换到另一台服务器. (10认同)
  • 我个人认为你应该做更多的验证.有人会尝试使用Bobby Table的电子邮件地址或更糟. (6认同)
  • 深度防御只有在你的安全洋葱的每个级别都没有腐烂时才有效.一个腐烂的层意味着你破坏整个洋葱.因为你想要防御Sun的μ律编码中的漏洞而拒绝"foo@example.com.au"是没有意义的,是吗?不要笑,这发生在我身上.我在这里评论的原因是,澳大利亚医疗保险不允许".au"地址,只允许".com".另请阅读Mark Swanson,"如何验证电子邮件",http://mdswanson.com/blog/2013/10/14/how-not-to-validate-email-addresses.html (4认同)

小智 16

我认为最好的方法如下:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

您可以在一般类中使用此静态函数.


Kni*_*ins 13

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

这些方法:

  • 经过试用和测试.这些方法用于我自己的专业项目中.

  • 在内部使用正则表达式,它们可靠且快速.

  • 由Microsoft为C#制作.没有必要重新发明轮子.

  • 返回bool结果.True表示电子邮件有效.

适用于.Net 4.5及更高版本的用户

将此参考添加到您的项目:

System.ComponentModel.DataAnnotations

现在您可以使用以下代码:

(new EmailAddressAttribute().IsValid("youremailhere@test.test"));
Run Code Online (Sandbox Code Playgroud)

使用示例

以下是一些声明方法:

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;

}
Run Code Online (Sandbox Code Playgroud)

......以及在行动中展示它们的代码:

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());

}
Run Code Online (Sandbox Code Playgroud)

另外,这个例子:

  • 扩展超出规范,因为单个字符串用于包含0,一个或多个由分号分配的电子邮件地址;.
  • 清楚地演示如何使用EmailAddressAttribute对象的IsValid方法.

替代方案,适用于.Net版本小于4.5的用户

对于.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;

}
Run Code Online (Sandbox Code Playgroud)


Jai*_*ath 11

简短准确的代码

public static bool IsValidEmail(this string email)
        {
            string pattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" + @"([-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);
        }
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的解决方案 (2认同)
  • 必须删除“ THIS”,以避免在将其添加到我的表单时引起编译器问题。 (2认同)

Noo*_*ilk 8

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

我永远不会在一个完全验证电子邮件的地方.你知道我怎么看它是否真的有效?如果它被发送.如果没有,那就糟糕了,如果确实如此,生活就是好的.这就是我需要知道的全部内容.


Mat*_*ock 6

我发现这个正则表达式在检查除了@标记之外的东西和接受奇怪的边缘情况之间是一个很好的权衡:

^[^@\s]+@[^@\s]+(\.[^@\s]+)+$
Run Code Online (Sandbox Code Playgroud)

它至少会让你在@标记周围添加一些东西,并至少放一个看起来很正常的域名.


Vas*_*dov 6

我总结了截至 2021 年我在这门课上为自己写的所有上述答案:

public static class StringExt {
    private const string emailPattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|" 
            + @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)" 
            + @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";

    public static bool IsValidMailAddress(this string pThis) 
            => pThis is not null 
            && Regex.IsMatch(pThis, emailPattern, RegexOptions.IgnoreCase);
}
Run Code Online (Sandbox Code Playgroud)


Mau*_*fer 5

电子邮件地址验证并不像看起来那么容易。实际上,仅使用正则表达式完全验证电子邮件地址在理论上是不可能的。

查看我的博客文章,了解有关该主题的讨论以及使用 FParsec 的 F# 实现。[/shameless_plug]

  • @matthew 我不知道为什么 IETF 甚至允许这样做,但它*可能*,因此必须进行彻底的验证。 (3认同)

Ral*_*h N 5

这是我的答案 - Phil 的解决方案对于像“someone@q.com”这样的单字母域失败。不管你信不信,这就是 =)(例如,转到 centurylink)。

Phil 的答案也只适用于 PCRE 标准……所以 C# 会接受它,但 javascript 会崩溃。对于 javascript 来说太复杂了。所以你不能使用Phil的解决方案来验证mvc属性。

这是我的正则表达式。它将与 MVC 验证属性很好地配合使用。
- @ 之前的所有内容都被简化,因此至少 javascript 可以工作。只要交换服务器不给我 5.1.3,我就可以在这里放松验证。- @ 之后的所有内容都是 Phil 针对单字母域修改的解决方案。

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]$";
Run Code Online (Sandbox Code Playgroud)

对于建议使用 system.net.mail MailMessage() 的人来说,这太灵活了。当然,C# 会接受电子邮件,但一旦您尝试发送电子邮件,交换服务器就会出现 5.1.3 运行时错误。


Man*_*chs 5

我只想指出,最近在 .NET 文档中增加了一个关于电子邮件验证的内容,也使用了 Regex 操作。可以在那里找到对其实施的彻底解释。

https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format

为方便起见,以下是他们的测试结果列表:

//       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.??
Run Code Online (Sandbox Code Playgroud)