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


当前回答

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

在“尝试块”发送一个验证电子邮件。 让用户打开电子邮件并单击一个链接,以验证电子邮件是真实的。

在此过程成功完成之前,该电子邮件被认为是无效的。

我根据维基百科的规则和样本地址创建了一个电子邮件地址验证程序。对于那些不介意多看一点代码的人,这里。说实话,我不知道电子邮件地址规范中有这么多疯狂的规则。我没有完全验证主机名或ipaddress,但它仍然通过了维基百科上的所有测试用例。

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

短而准确的代码

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

在c#的regex中有文化问题,而不是js。所以我们需要在US模式下使用regex进行邮件检查。如果你不使用ECMAScript模式,你的语言特殊字符是在A-Z与正则表达式中隐含的。

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)