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


当前回答

我认为最好的方法如下:

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

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

其他回答

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

这似乎是可行的,而且在我看来是相当优雅的:

using System.ComponentModel.DataAnnotations;

class ValidateSomeEmails
{
    static void Main(string[] args)
    {
        var email = new EmailAddressAttribute();
        email.IsValid("someone@somewhere.com");         //true
        email.IsValid("someone@somewhere.co.uk");       //true
        email.IsValid("someone+tag@somewhere.net");     //true
        email.IsValid("futureTLD@somewhere.fooo");      //true
        
        email.IsValid("fdsa");                          //false
        email.IsValid("fdsa@");                         //false
        email.IsValid("fdsa@fdsa");                     //false
        email.IsValid("fdsa@fdsa.");                    //false

        //one-liner
        if (new EmailAddressAttribute().IsValid("someone@somewhere.com")) 
            return true;
    }
}

以前,我写了一个EmailAddressValidationAttribute,它应该正确地验证表单中几乎任何相对正常的电子邮件地址

local-part@domain

它是System.ComponentModel.DataAnnotations。ValidationAttribute,所以使用非常简单。

而且,由于挖掘所有rfc和勘误表,并组装所需的所有位来正确枚举所有规则……太乏味了!-我在回答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., jsmith@whizbang.com (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 <jsmith@whizbang.com>) 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 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.

Personally, I would say that you should just make sure there is an @ symbol in there, with possibly a . character. There's many regexes you could use of varying correctness, but I think most of these leave out valid email addresses, or let invalid ones through. If people want to put in a fake email address, they will put in a fake one. If you need to verify that the email address is legit, and that the person is in control of that email address, then you will need to send them an email with a special coded link so they can verify that it indeed is a real address.

我经常用这个来验证电子邮件,它就像一个魅力。这验证了电子邮件必须在@之前至少有一个字符,并且在“”之前至少有一个字符。

public static bool ValidateEmail(string value, bool required, int minLength, int maxLength)
        {
           value = value.Trim();
           if (required == false && value == "") return true;
           if (required && value == "") return false;
           if (value.Length < minLength || value.Length > maxLength) return false;

           //Email must have at least one character before an @, and at least one character before the .
           int index = value.IndexOf('@');
           if (index < 1 || value.LastIndexOf('.') < index + 2) return false;
           return true;
        }

我总结了以上所有的答案,截至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);
}