多年来,我慢慢地开发了一个正则表达式,它可以正确验证大多数电子邮件地址,假设它们不使用IP地址作为服务器部分。
我在几个PHP程序中使用它,而且大多数时候都可以使用。然而,不时有人与我联系,他们对使用它的网站有问题,我最终不得不做出一些调整(最近我意识到我不允许四个字符的TLD)。
你有或见过验证电子邮件的最佳正则表达式是什么?
我见过几种使用函数的解决方案,这些函数使用了几个较短的表达式,但我宁愿在简单函数中使用一个长的复杂表达式,而不是在更复杂的函数中使用几个短表达式。
多年来,我慢慢地开发了一个正则表达式,它可以正确验证大多数电子邮件地址,假设它们不使用IP地址作为服务器部分。
我在几个PHP程序中使用它,而且大多数时候都可以使用。然而,不时有人与我联系,他们对使用它的网站有问题,我最终不得不做出一些调整(最近我意识到我不允许四个字符的TLD)。
你有或见过验证电子邮件的最佳正则表达式是什么?
我见过几种使用函数的解决方案,这些函数使用了几个较短的表达式,但我宁愿在简单函数中使用一个长的复杂表达式,而不是在更复杂的函数中使用几个短表达式。
当前回答
根据W3C HTML5规范:
^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$
上下文:
有效的电子邮件地址是与ABNF生产[…]匹配的字符串。注意:这一要求故意违反了RFC 5322,RFC 5322为电子邮件地址定义了一种语法,该语法同时太严格(在“@”字符之前)、太模糊(在“@”字符之后)和太松散(允许注释、空白字符和引用字符串以大多数用户不熟悉的方式),在这里无法实际使用。以下JavaScript和Perl兼容的正则表达式是上述定义的实现。/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9]?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
其他回答
没有一个是真正有用的。我在回答“是否有用于电子邮件地址验证的PHP库?”时讨论了一些问题?,它也在电子邮件地址的正则表达式识别难吗?中讨论?。
简而言之,不要期望一个可用的正则表达式能够完成正确的工作。最好的正则表达式将验证语法,而不是电子邮件的有效性(jhohn@example.com是正确的,但它可能会反弹…)。
根据W3C HTML5规范:
^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$
上下文:
有效的电子邮件地址是与ABNF生产[…]匹配的字符串。注意:这一要求故意违反了RFC 5322,RFC 5322为电子邮件地址定义了一种语法,该语法同时太严格(在“@”字符之前)、太模糊(在“@”字符之后)和太松散(允许注释、空白字符和引用字符串以大多数用户不熟悉的方式),在这里无法实际使用。以下JavaScript和Perl兼容的正则表达式是上述定义的实现。/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9]?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
根据我的理解,它很可能会被。。。
/^([a-z0-9_-]+)(@[a-z0-9-]+)(\.[a-z]+|\.[a-z]+\.[a-z]+)?$/is
如果您可以接受空值(这不是无效的电子邮件),并且正在运行PHP 5.2+,我建议您:
static public function checkEmail($email, $ignore_empty = false) {
if($ignore_empty && (is_null($email) || $email == ''))
return true;
return filter_var($email, FILTER_VALIDATE_EMAIL);
}
我不相信bortzmeyer所说的“语法(RFC 5322中指定的)太复杂了”(无法用正则表达式处理)。
这是语法(来自3.4.1。添加规范规范):
addr-spec = local-part "@" domain
local-part = dot-atom / quoted-string / obs-local-part
domain = dot-atom / domain-literal / obs-domain
domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext = %d33-90 / ; Printable US-ASCII
%d94-126 / ; characters not including
obs-dtext ; "[", "]", or "\"
假设点原子、带引号的字符串、obs局部部分、obs域本身是正则语言,这是一个非常简单的语法。只需将addr-spec产品中的本地部分和域替换为它们各自的产品,您就拥有了一种可直接转换为正则表达式的正则语言。