多年来,我慢慢地开发了一个正则表达式,假设它们不使用IP地址作为服务器部件,则可以正确验证MOST电子邮件地址。
我在几个PHP程序中使用了它,并且大多数时候都可以使用。但是,有时会遇到某个使用它的站点出现问题的人与我联系,最终我不得不进行一些调整(最近我意识到我不允许使用4个字符的TLD)。
您已经或看到的用于验证电子邮件的最佳正则表达式是什么?
我已经看到了几种使用使用几个较短表达式的函数的解决方案,但是我宁愿在一个简单函数中使用一个长的复杂表达式,而不是在一个更复杂的函数中使用几个短的表达式。
由于其长度,完全符合RFC 822的正则表达式效率低下且晦涩难懂。幸运的是,RFC 822被取代了两次,当前电子邮件地址规范为RFC 5322。RFC 5322导致了一个正则表达式,如果研究几分钟,它可以被理解并且对于实际使用足够有效。
可以在页面顶部的http://emailregex.com/上找到一个符合RFC 5322的正则表达式,但是它使用的IP地址模式在Internet上浮动,并且存在一个错误,该错误允许00在地址栏中输入任何未签名的字节十进制值以点分隔的地址,这是非法的。它的其余部分似乎与RFC 5322语法一致,并且使用进行了多次测试grep -Po,包括大小写域名,IP地址,错误的地址以及带引号和不带引号的帐户名。
纠正00IP模式中的错误后,我们获得了一个有效且相当快速的正则表达式。(对于实际代码,请删除渲染的版本,而不是降价版本。)
(?:[a-z0-9!#$%&'* + / =?^ _`{|}〜-] +(?:\。[a-z0-9!#$%&'* + / =?^ _`{|}〜-] +)* |“(?:[\ x01- \ x08 \ x0b \ x0c \ x0e- \ x1f \ x21 \ x23- \ x5b \ x5d- \ x7f] | \\ [\ x01- \ x09 \ x0b \ x0c \ x0e- \ x7f])*))@(?:(?:[a-z0-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] | [0-4] [0-9])| 1 [0-9] [0-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])+)\])
要么:
(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-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]|[0-4][0-9])|1[0-9][0-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对其进行验证绝对不会告诉您该地址是否确实存在于提供的域中,或者输入地址的人是否是其真实所有者。人们一直以这种方式签署邮件列表。需要进行更高级验证的修补程序,包括向该地址发送一条消息,其中包含要与该地址输入同一网页的确认令牌。
确认令牌是知道您获得输入者地址的唯一方法。这就是为什么大多数邮件列表现在都使用该机制来确认注册的原因。毕竟,任何人都可以放下脚步president@whitehouse.gov,这甚至可以解析为合法的,但不可能是另一端的人。
对于PHP,你应该不使用给定的模式验证与PHP的电子邮件地址,正道从我引述如下:
存在某种危险,即通常的用法和广泛的草率编码将为电子邮件地址建立事实上的标准,该标准比记录的正式标准更具限制性。
这并不比所有其他非RFC模式都好。它甚至不是足够聪明,可以处理RFC 822,更不用说RFC 5322这一个,但是,是。
如果您想花哨和学究,请实施一个完整的状态引擎。正则表达式只能充当基本过滤器。正则表达式的问题在于,告诉某人其完全有效的电子邮件地址是无效的(误报),因为从用户的角度来看,您的正则表达式无法处理它只是不礼貌和不礼貌。用于此目的的状态引擎既可以验证甚至更正电子邮件地址,否则该地址将被视为无效,因为它会根据每个RFC分解电子邮件地址。这样可以带来更愉悦的体验,例如
指定的电子邮件地址“ myemail @ address,com”无效。您是说“ myemail@address.com”吗?