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


461

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




还有许多其他重要的验证方法,不仅是字符串,还最好检查此smtp服务器上是否存在该电子邮件,或者用户正在输入任何电子邮件..等等,或者使用将为您处理该电子邮件的API以确保像ver-email.com
Amr

来自Microsoftdocs.microsoft.com/zh-cn/dotnet/standard/base-types/…的最佳建议
Kishore Sahasranaman

Answers:


783

那这个呢?

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)的拼写错误,等等。然后向用户显示警告有机会说“是的,我的邮件服务器确实允许🌮🍳🎁作为电子邮件地址。”


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

此外,如果您对电子邮件地址进行任何其他操作,则可能涉及将其转换为MailAddress。即使您不使用此确切功能,您也可能希望使用相同的模式。您还可以通过捕获不同的异常来检查特定类型的故障:空,空或无效格式。


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


---进一步阅读---

System.Net.Mail.MailAddress的文档

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


23
实际上,这是不正确的。a @ a是有效的电子邮件地址。请参阅haacked.com/archive/2007/08/21/… 实际上,如果您使用带引号的地址,则此方法不会返回错误的结果。
齿轮

53
+1:如果您使用的是System.Net.Mail类来发送邮件,那么这是最好的答案;如果您使用的是.NET,则可能是这样。我们决定使用这种类型的验证只是因为我们没有接受我们无法发送邮件的电子邮件地址(甚至是有效的电子邮件地址)的意义。
格雷格·比奇

24
我不推荐。它返回true:IsValidEmail("this is not valid@email$com");
Kakashi

15
许多问题似乎是因为MailAddress也尝试解析DisplayName,所以“单个space@domain.com”解析为DisplayName“单个”和地址“ space@domain.com”。一个解决方法是:return(addr.Address == email);
斯图尔特2014年

18
我喜欢这个; 我不强迫自己比实际规范更具限制性。误报比误报要严重得多(“您的意思是我的电子邮件无效吗? ”)
Casey 2014年

241

这是一个古老的问题,但是我在SO上找到的所有答案(包括最近的答案)都与此答案类似。但是,在.Net 4.5 / MVC 4中,您可以通过从System.ComponentModel.DataAnnotations添加[EmailAddress]批注来向表单添加电子邮件地址验证,因此我想知道为什么我不能仅使用.NET的内置功能。网一般。

这似乎可行,在我看来也相当优雅:

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

4
很酷,尽管MS不能使这一点与他们自己的文档一致令人失望。这拒绝了js@proseware.com9
Casey

13
请注意,EmailAddressAttribute它比System.Net.Mail.MailAddress-例如MailAddress接受TLD的地址所允许的少。如果您需要尽可能地宽容,请记住一些注意事项。
Aaroninus 2015年

5
@Cogwheel:如果答案在注释中某处,则可能应将其添加到答案的主体中。
hofnarwillie 2015年

6
@hofnarwillie:它在主体中,但评论详尽。如果您的目标是不激怒用户,那么您的验证就不应比规范更具限制性。真正验证电子邮件是否有效的唯一方法是发送测试消息。
齿轮

4
请注意foo.IsValid(null);返回true
urig

62

我使用这种单衬板方法对我有用

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

根据注释,如果source(电子邮件地址)为null ,则此操作将“失败” 。

public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);

1
这对我不起作用;我得到,“'数据注释'不存在...您是否缺少程序集引用?” 我需要添加哪个参考?
B. Clay Shannon,

如果source为null,则返回true。请参阅msdn.microsoft.com/zh-cn/library/hh192424 “如果指定的值有效或为null,则为true;否则为false。”
jao

2
更好的版本:public static Boolean IsValidMailAddress(this String pThis) => pThis == null ? false : new EmailAddressAttribute().IsValid(pThis);
塞巴斯蒂安·霍夫曼

7
甚至更好:public static bool IsValidEmailAddress(this string address) => address != null && new EmailAddressAttribute().IsValid(address);
Patrik Melander

1
我不认为此扩展方法应该静默返回false空字符串。这就是为什么我建议(甚至更好)++版本的原因public static bool IsValidEmailAddress(this string address) => new EmailAddressAttribute().IsValid(address ?? throw new ArgumentNullException());。现在,我去找改革更好的版本主义者教会。
Marc.2377

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])))\.?$";

2
不幸的是,EmaillAddressAttribute允许Ñ,这不是电子邮件的有效字符
BZ

16
@BZ是的。您为什么认为不是?
Casey 2014年

@Chad Grant:这是C#版本。能否请您提供一个VB.Net。因为那样会将\\转换为\,否则您可以逐字提供一个字符串。
Nikhil Agrawal,2015年

3
RegexOptions.IgnoreCase可行,但是请不要忘记,因为此模式不允许显式使用大写字母!
克里斯(Chris)

1
请注意,Regex是非常有意的:“此属性提供与jquery validate等效的服务器端电子邮件验证,因此共享相同的正则表达式”。
Ohad Schneider

38

我从第一名得到了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;
    }
}

5
只是一个很小的,但我会使用:return(!string.IsNullOrEmpty(emailAddress))&& ValidEmailRegex.IsMatch(emailAddress);
Marc 2013年

这简直是​​恐怖:)
Alexandru Dicu '16

31

就个人而言,我想说的是,您应该确保其中有一个@符号,可能还有一个。字符。您可以使用多种正则表达式来改变正确性,但我认为其中大多数会忽略有效的电子邮件地址,或者让无效的电子邮件地址通过。如果人们想输入伪造的电子邮件地址,他们将输入伪造的电子邮件地址。如果您需要验证电子邮件地址是合法的,并且该人可以控制该电子邮件地址,那么您将需要向他们发送一封带有特殊编码链接的电子邮件,以便他们可以验证该地址确实是真实地址。


6
我个人认为您应该做的更多验证工作。有人一定会尝试Bobby Table的电子邮件地址或更糟糕的地址。
路加·奎纳内

31
如果您使用准备好的语句,鲍比表的电子邮件地址怎么了?我们谈论的是有效的电子邮件地址,而不是与构成有效电子邮件地址无关的其他事情,例如如何正确执行SQL查询以免出现SQL注入问题。
Kibbee

我猜你不知道有人会把东西放在那里,但一个恶意的人知道这个价值最终可能会送到你的邮件系统中。我只想更深入地防守并变得更加严格。
路加·奎纳

10
这是邮件系统需要担心的。我不会仅仅因为它可能是某些其他系统的安全性问题而拒绝完全有效的电子邮件地址。如果您所有的电子邮件服务器需求都是格式不正确的电子邮件地址,以引起安全问题,则您可能应该切换到另一台服务器。
Kibbee

4
深度防御仅在安全洋葱的各个等级均未腐烂的情况下才有效。一层烂意味着您将整个洋葱变质。因为您想防御Sun的µ-law编码中的漏洞而拒绝“ foo@example.com.au”没有道理,是吗?别笑,这是发生在我身上。我在这里评论的原因是,澳大利亚Medicare不允许使用“ .au”地址,而只能使用“ .com”地址。另请阅读Mark Swanson的“如何不验证电子邮件”,mdswanson.com
blog /

17

我认为最好的方法如下:

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

您可以在常规类中使用此静态函数。


此答案不接受域部分中带有TLD的地址。
西蒙妮(Simone)

15

简短准确的代码

string Email = txtEmail.Text;
if (Email.IsValidEmail())
{
   //use code here 
}

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

2
感谢您的解决方案
Jack Gajanan

我不得不布尔IsValidEmail(此字符串电子邮件)变更公共静态公共静态布尔IsValidEmail(字符串email)来避免这个:stackoverflow.com/questions/10412233/...
完了道格

。@Goner道格,这functionlity将这样工作(布尔标志= EmailAddress.IsValidEmail())
纳温

2
必须删除“ THIS”,以避免在将其添加到我的表单时引起编译器问题。
格纳道格

@Goner Doug,其功能将像这样工作。字符串email =“ abc@xyz.com”; 如果(email.IsValidEmail()){返回false;} else {return true;}
纳芬(Naveen)

14

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

这些方法:

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

  • 在内部使用可靠且快速的正则表达式。

  • 由Microsoft为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());

}

另外,此示例:

  • 由于单个字符串用于包含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;

}

1
@ThomasAyoub我还没有看到EmailAddressAttribute的答案,也没有看到使用new MailAddress()并检查input == .Address的答案,所以我认为它非常有用。不阅读评论,接受的答案是完全错误的。新的MailAddress(“ Foobar Some@thing.com”)证明了这一点。

@Jan fwiw,ManikEmailAddressAttribute在不到四个月的时间内击败了Knickerless ,尽管这个确实抓住了这个null问题。
鲁芬

7

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

我永远无法完全验证电子邮件。你知道我怎么看它真的有效吗?如果发送了。如果没有,那就很糟糕,如果做到了,那将是生活的美好。这就是我所需要知道的。


6

我发现此正则表达式在检查不仅仅是@标记的内容与接受奇怪的边缘情况之间是一个很好的权衡:

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

至少会使您在@标记周围加上一些内容,并至少使它看起来正常。


我想出了同一个正则表达式;)虽然确实允许无效字符
Stefan

此答案在域部分不接受TLD。
西蒙妮(Simone)

尽管实际上,@ Simone可能没有人在域部分中具有TLD的电子邮件地址:serverfault.com/a/721929/167961在注释中指出,这些天可能会被禁止
马修·洛克

@MatthewLock可以是Intranet地址吗?喜欢bob@companyinternal吗?
西蒙妮

@Simone在现实生活中有没有人真正使用过该方案?
马修·洛克

4

电子邮件地址验证并不像看起来那样容易。从理论上讲,实际上仅使用正则表达式完全无法验证电子邮件地址。

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


1
我喜欢您列出的替代方法;很有意思。
路加·奎纳内

1
有趣的文章。但是认真的是谁在电子邮件地址中添加评论,并在其中嵌套评论呢?
马修·洛克

3
@matthew我不知道为什么IETF甚至允许这样做,但是有可能,因此必须进行全面的验证。
Mauricio Scheffer

4

这是我的答案-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]$";

对于建议使用system.net.mail MailMessage()的人来说,这很灵活。当然,C#会接受电子邮件,但是一旦您尝试发送电子邮件,Exchange服务器将以5.1.3运行时错误轰炸。


这似乎是最好,最周到/合理/真实的答案,谢谢拉尔夫!
Fattie 2014年

这是迄今为止最好的答案!我不敢相信接受basket@ball有效电子邮件地址的错误解决方案会获得正确答案以及所有这些支持。不管怎么说,还是要谢谢你!
2015年

谢谢,这是最好的解决方案,应该被接受。
Bat_Programmer

3

如果您和我的意思是真的想知道一个电子邮件地址是否有效...请向邮件交换者证明它,则不需要正则表达式。如果需要,我可以提供代码。

常规步骤如下:1.电子邮件地址是否包含域名部分?(@的索引> 0)2.使用DNS查询询问域是否具有邮件交换器3.打开到邮件交换器的tcp连接4.使用smtp协议,使用电子邮件地址作为接收者打开到服务器的消息5。解析服务器的响应。6.如果您已经做到了,请退出该消息,一切都很好。

您可以想象,这是非常昂贵的时间,并且依赖于smtp,但是它确实起作用。


您是否为这些接口创建了伪造品,存根和/或模拟?
标记

1
那行不通。验证电子邮件地址的smtp协议已被弃用/未使用。由于垃圾邮件发送者使用该功能,因此在邮件服务器上启用该功能被认为是不好的做法。
乍得·格兰特

我将把您的建议保持在第2点。与检查已知的域名模式相比,它具有更多的面向未来的能力。
西蒙妮(Simone)

细细挑选,但定义“具有邮件交换器”?如果不存在MX记录,则SMTP应回退到A / AAAA记录(根据RFC2821 / 5321)。如果确实存在MX记录,则它可能仍不表示邮件交换器存在(RFC7505)。确实,唯一的方法是向他们发送带有号召性
用语

2

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

我强烈建议您尝试使用我们的EmailVerify.NET,这是一个成熟的.NET库,可以验证所有以下地址的电子邮件地址符合当前IETF标准(RFC 1123,RFC 2821,RFC 2822,RFC 3696,RFC 4291,RFC 5321和RFC 5322)的,测试相关的DNS记录,检查目标邮箱是否可以接受邮件,甚至可以判断给定的地址是否为一次性地址。

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


令人印象深刻!“接下来,它尝试与负责给定电子邮件地址的邮件交换器联系,并与该服务器开始伪造的SMTP对话框,以模拟真实的邮件服务器。这样可以确保该服务器可以处理该地址的电子邮件。许多SMTP服务器实际上给出错误的肯定答案以防止垃圾邮件发件人:为解决此问题,EmailVerify for .NET最终尝试使用不同的伪造地址多次查询目标邮件交换器。“
Matthew Lock

谢谢@MatthewLock;)
Efran Cobisi 2015年

很好,但我只看到付费版本。有社区/开放源代码版本的计划吗?
Ohad Schneider

1
@OhadSchneider是:我们通过Verifalia(我们的SaaS 电子邮件验证服务)提供了免费版本的电子邮件验证技术。Verifalia随附了用于主要软件开发平台(包括.NET)的免费和开源SDK 。
Efran Cobisi

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

它将无法验证a@b.info为有效的电子邮件地址。
Ray Cheng

2

如果您使用的是FluentValidation,则可以这样编写:

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;

2

对@Cogwheel答​​案进行一些修改

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

这似乎没有帮助... Console.WriteLine(MailAddress("asdf@asdf.").Address);输出“ asdf @ asdf。”,这是无效的。
兰登'18

.net似乎有其有效的定义。相关讨论
waitforit

2

这里有很多强有力的答案。但是,我建议我们退后一步。@Cogwheel回答了问题https://stackoverflow.com/a/1374644/388267。但是,如果许多正在验证的电子邮件地址无效,则在批量验证方案中可能会付出高昂的代价。我建议在进入他的try-catch块之前,请先运用一些逻辑。我知道以下代码可以使用RegEx编写,但对于新开发人员而言,理解起来可能代价很高。这是我的两便士的价值:

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

2

@Cogwheel投票最多的答案是最好的答案,但是我尝试实现trim()字符串方法,因此它将修剪从字符串开始到结尾的所有用户空白。查看下面的代码查看完整示例-

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

这样做的风险是,您要验证的电子邮件地址与源地址不同,从而使您认为可以将邮件发送到(在这种情况下)指定电子邮件地址的未修饰版本。更好的方法是采用一种单独的方法SanitizeEmail(string email),使用该方法的结果来验证并将电子邮件发送至。
Marco de Zeeuw,

1
private static bool IsValidEmail(string emailAddress)
{
    const 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).IsMatch(emailAddress);
}

1

通过以下方法检查电子邮件字符串是正确格式还是错误格式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";
        }
    }

1

/使用用于创建“新的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/zh-CN/library/01escwtf(v=vs.110).aspx


它说,这个电子邮件真:“fulya_42_@hotmail.coö”,它在山魈API抛出错误
MonsterMMORPG

1
首先,该电子邮件在example@example.co或example@example.com ...上是有效的。该电子邮件具有所有有效的字符串和条件,但最后一个字符“ö”除外,您可以轻松地添加一个简单条件来验证该字符。其次,不确定那个mandrill api错误,您可能想验证您的使用方法bcos我已经在其他一些环境/ api上使用了此验证,这对我很有用。
Aina Ademola C

1

我将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);
}

1

识别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})(\]?)$");
}

1

C#而不是js中的正则表达式中存在文化问题。因此,我们需要在美国模式下使用正则表达式进行电子邮件检查。如果您不使用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)

1

我最终使用了此正则表达式,因为它成功验证了逗号,注释,Unicode字符和IP(v4)域地址。

有效地址为:

“” @ example.org

(评论)test@example.org

тест@example.org

example@example.org

测试@ [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,}))$";

1

一个不使用Regex的简单代码(我不喜欢它的可读性差):

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("a.b@com") // false
  • IsValidEmail("a@b.") // false
  • IsValidEmail("a b@c.com") // false
  • IsValidEmail("a@b c.com") // false
  • IsValidEmail("a@b.com") // true
  • IsValidEmail("a@b.c.com") // true
  • IsValidEmail("a+b@c.com") // true
  • IsValidEmail("a@123.45.67.89") // true

它的意思是简单,因此不会处理罕见的情况,例如带有带括号的域的电子邮件(通常允许),带有IPv6地址的电子邮件等。


1

这是您的问题的答案供您检查。

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;

   }

}

1

基于@Cogwheel的答案,我想共享一种适用于SSIS和“脚本组件”的修改后的解决方案:

  1. 将“脚本组件”放入数据流连接中,然后将其打开。
  2. 在“输入列”部分中,将包含电子邮件地址的字段设置为“ ReadWrite”(在示例“ fieldName”中)。
  3. 切换回“脚本”部分,然后单击“编辑脚本”。然后,您需要在代码打开后等待。
  4. 将此代码放在正确的方法中:

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

然后,您可以使用条件拆分来过滤掉所有无效记录或您想执行的任何操作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.