是否有人知道根据RFC5321 / RFC5322验证电子邮件地址的正则表达式?
由于(可嵌套)注释使语法不规则,因此只应考虑没有注释的地址。
当然,如果您有兴趣验证某人实际拥有的地址,那么唯一真正的验证是向该地址发送电子邮件并检查所有者是否收到该地址。然而,我对RFC标准纯粹感兴趣。实际方法this question更具相关性。
除了评论之外,我愿意牺牲折叠空白区域,但除此之外,我对拒绝任何RFC5321 / 2有效地址的表达式不感兴趣。 (可以说在某些情况下甚至可以忽略折叠的空白区域。)
理想情况下,正则表达式会拒绝任何不 RFC-valid的内容,但这并不重要。例如,在正则表达式中包含一个详尽的顶级域名列表并不是那么有趣。只需接受任何顶级域名即可。
我不确定地址标记(例如地址+ tag@domain.org)是否是我提到的RFC的一部分,但我希望正则表达式验证这些。
IPv6应该正确处理(RFC5952)。
据我所知,国际化电子邮件(RFC6530,RFC6531,RFC6532,RFC6533)仍处于试验阶段,但验证这些地址的表达式也会很有趣
为了使答案普遍有趣,如果任何正则表达式都是POSIX格式,那将是很好的。
答案 0 :(得分:14)
不稳定的评论使电子邮件地址的语法不规则(无上下文)。但是,如果您排除了注释,则生成的语法是常规的。主要定义允许(折叠)词汇标记之间的空格(例如a @ b.com
)。删除所有折叠空格会产生规范形式。
根据RFC 5322(排除评论),这是规范电子邮件地址的正则表达式:
([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])
如果你需要接受折叠空格,那么这是根据RFC 5322(排除评论)的电子邮件地址的正则表达式:
((([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?"(((([\t ]*\r\n)?[\t ]+)?([]!#-[^-~]|(\\[\t -~])))+(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?)"(([\t ]*\r\n)?[\t ]+)?)@((([\t ]*\r\n)?[\t ]+)?[-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*(([\t ]*\r\n)?[\t ]+)?|(([\t ]*\r\n)?[\t ]+)?\[((([\t ]*\r\n)?[\t ]+)?[!-Z^-~])*(([\t ]*\r\n)?[\t ]+)?](([\t ]*\r\n)?[\t ]+)?)
RFC 5321(SMTP)中进一步限制了有效的电子邮件地址。它基本上只留下@ -sign之前的部分,但在@ -sign之后只接受主机名或地址文字。 (" --- .---"是一个有效的点原子,但不是有效的主机名," [...]"是一个有效的域文字,但是不是有效的地址文字。)
RFC 5321中提供的语法在主机名和IP地址方面都过于宽泛。我冒昧地纠正了#34;有问题的规则,使用this draft和RFC 1034(第3.5节)作为指导原则。这是由此产生的正则表达式。
([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])
所有正则表达式都是POSIX ERE。最后一个使用负向前瞻。有关正则表达式的派生,请参阅here。
答案 1 :(得分:-1)
更新:
正如Michael Stramel所说,RFC822已经过时,请参阅他的评论。
据我所知RFC822指定了电子邮件地址语法。