如何使用正则表达式验证电子邮件地址?

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

我在几个PHP程序中使用它,并且大多数时候都能正常工作。然而,有时我会与使用它的网站有问题的人联系,最后我不得不做一些调整(最近我意识到我不允许使用四个字符的TLD)

验证电子邮件的最佳正则表达式是什么?

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

完全符合RFC 822的正则表达式由于其长度而效率低下且晦涩难懂。幸运的是,RFC 822被两次取代,当前的电子邮件地址规范是RFC 5322。RFC5322生成了一个正则表达式,如果研究几分钟就可以理解,并且对于实际使用来说足够有效

在页面顶部的以下位置可以找到一个符合RFC 5322的正则表达式:http://emailregex.com/ 但使用的IP地址模式在internet上四处浮动,并带有一个错误,该错误允许00查找点分隔地址中的任何无符号字节十进制值,这是非法的。其余部分似乎与RFC 5322语法一致,并通过了使用grep-Po的多项测试,包括域名、IP地址、坏域名和带引号和不带引号的帐户名

纠正了IP模式中的00错误,我们获得了一个运行良好且速度相当快的正则表达式。(刮取渲染版本,而不是标记,以获取实际代码。)

(以下简称::[a-z0-9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 z0-9-]*[a-z0-9]?\)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\[(?:(?:(?:(2(5[0-5]|[0-4][0-9])| 1[0-9][0-9]|[1-9]|[0-9])\){3:(2(5[0-5]1240-4][0-9]);1[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)

或:

<<<>(以下以下以下简称:[a-z0-z0-10-9-9-9.[a-z0-0-5-9手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手手(?:[a-z0-9-]*[a-z0-9])?\)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\[(?:(?:(2(5[0-5]|[0-4][0-9])1[0-9][0-9]|[1-9]|[0-9])\){3:(2(5[0-5]1240-4][0-9][1-9]|[1-9]?[0-9]。[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]。\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)

下面是上述regexp的有限状态机图,它比regexp本身更清晰

Perl和PCRE中更复杂的模式(例如在PHP中使用的正则表达式库)可以顺利地正确解析RFC 5322。Python和C#也可以做到这一点,但它们使用的语法与前两种不同。但是,如果您被迫使用许多功能较弱的模式匹配语言中的一种,那么最好使用真正的解析器

同样重要的是要了解,根据RFC验证它绝对不会告诉您该地址是否确实存在于提供的域中,或者输入该地址的人是否是它的真正所有者。人们总是以这种方式向其他人注册邮件列表。要解决这一问题,需要一种更奇特的验证,包括es向该地址发送包含确认令牌的消息,该令牌将被输入到与该地址相同的网页上

确认令牌是知道您获得输入者地址的唯一方法。这就是为什么大多数邮件列表现在使用该机制来确认注册。毕竟,任何人都可以输入[email protected],这甚至会被解析为合法,但不太可能是另一端的人

对于PHP,您应该而不是使用PHP验证电子邮件地址中给出的模式,我引用的正确方式如下:

常见用法和广泛使用的草率编码可能会为电子邮件地址建立一个事实上的标准,该标准比记录的正式标准更具限制性

这并不比所有其他非RFC模式好。它甚至不足以处理RFC 822,更不用说RFC 5322了。然而,这一个是

如果您想变得花哨和迂腐,请实现一个完整的状态引擎。正则表达式只能充当基本的筛选器。正则表达式的问题在于告诉某人其完全有效的电子邮件地址无效(误报)因为您的正则表达式无法处理,所以从用户的角度来看,这是粗鲁和不礼貌的。用于此目的的状态引擎既可以验证电子邮件地址,甚至可以更正电子邮件地址,否则这些地址将被视为无效,因为它会根据每个RFC分解电子邮件地址。li说,这可能会带来更愉快的体验ke

指定的电子邮件地址’[email protected],com’无效。您的意思是’[email protected]”“是吗

另请参见验证电子邮件地址,包括注释。或比较电子邮件地址验证正则表达式

调试程序演示

发表评论