多年来,我慢慢地开发了一个正则表达式,它可以正确验证大多数电子邮件地址,假设它们不使用IP地址作为服务器部分。

我在几个PHP程序中使用它,而且大多数时候都可以使用。然而,不时有人与我联系,他们对使用它的网站有问题,我最终不得不做出一些调整(最近我意识到我不允许四个字符的TLD)。

你有或见过验证电子邮件的最佳正则表达式是什么?

我见过几种使用函数的解决方案,这些函数使用了几个较短的表达式,但我宁愿在简单函数中使用一个长的复杂表达式,而不是在更复杂的函数中使用几个短表达式。


当前回答

我用这个;

^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[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,}))$

其他回答

您可以使用jQuery Validation插件使用的方法:

/^((([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])))\.?$/i

我不建议使用正则表达式,电子邮件地址太复杂了。这是一个常见的问题,所以我猜有很多库都包含验证器-如果您使用Java,apachecommons验证器的EmailValidator是一个很好的验证器。

根据我所看到的,一个完全符合标准的正则表达式是允许的:

/^(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}.+@)([a-z\xC0-\xFF0-9!#$%&'*+\/=?^_`{|}~.-]+@)(?!.{253}.+$)((?!-.*|.*-\.)([a-z0-9-]{1,63}\.)+[a-z]{2,63}|(([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9]))$/gim

演示/调试分析(交互式)

拆分:

^(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}.+@)
([a-z\xC0-\xFF0-9!#$%&'*+\/=?^_`{|}~.-]+@)
(?!.{253}.+$)
(
    (?!-.*|.*-\.)
    ([a-z0-9-]{1,63}\.)+
    [a-z]{2,63}
    |
    (([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}
    ([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])
)$

分析:

(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}.+@)

对以。,以一结尾,有。。或超过254个字符的最大长度


([a-z\xC0-\xFF0-9!#$%&'*+\/=?^_`{|}~.-]+@)

匹配一个或多个允许的字符,并应用负面外观


(?!.{253}.+$)

域名部分的负前瞻性,总共限制为253个字符


(?!-.*|.*-\.)

每个域名的负前瞻性,不允许以开头或结尾。


([a-z0-9-]{1,63}\.)+

域名中允许的字符的简单组匹配,每个字符限制为63个字符


[a-zA-Z]{2,63}

允许的顶级域的简单组匹配,该域目前仍仅限于字母,但确实包含4个字母以上的TLD。


(([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}
([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])

域名的替代方案:这将IP地址中的前3个数字与匹配。然后是IP地址中没有的第四个数字。在它背后。

这是我使用的PHP代码。我选择这个解决方案是出于“误报比误报好”的精神,正如这里的另一位评论者所说的,并考虑到保持您的响应时间并降低服务器负载。。。当正则表达式可以消除大多数简单的用户错误时,真的不需要浪费服务器资源。如果你愿意,你可以随时通过发送测试邮件来跟进。

function validateEmail($email) {
  return (bool) stripos($email,'@');
}

也许是最好的:

/^[a-zA-Z0-9]+([-._][a-zA-Z0-9]+)*@[a-zA-Z0-9]+([-.][a-zA-Z0-9]+)*\.[a-zA-Z]{2,7}$/

以字母或数字开头。它可能包括“-__”,以“.”结尾,并且少于七个字符(例如.company)。