Regular Expressions 匹配电子邮件地址

示例

在字符串中匹配电子邮件地址是一项艰巨的任务,因为定义它的规范RFC2822很复杂,很难实现为正则表达式。有关为什么将电子邮件与正则表达式匹配不是一个好主意的更多详细信息,请在不使用正则表达式时参考反模式示例:匹配电子邮件。在该页面上要注意的最佳建议是使用您喜欢的语言并经过同行评审并广泛使用的库来实现此目的。

验证电子邮件地址格式

当您需要快速验证条目以确保它看起来像电子邮件时,最好的选择是使其简单:

^\S{1,}@\S{2,}\.\S{2,}$

该正则表达式将检查邮件地址是否是长度大于1的非空格分隔字符序列,后接an @,然后是长度为2或更大且由a分隔的两个非空格字符序列.。它不是完美的,并且可能会验证无效地址(根据格式),但最重要的是,它不会使有效地址无效。

检查地址是否存在

检查电子邮件是否有效的唯一可靠方法是检查电子邮件的存在。曾经有VRFY为此目的而设计的SMTP命令,但可悲的是,在被垃圾邮件发送者滥用后,该命令现在不再可用。

因此,剩下的检查邮件是否有效和唯一的方法就是实际发送电子邮件到该地址。

正则表达式的巨大替代品

不过,使用正则表达式验证地址电子邮件并非并非不可能。唯一的问题是,这些正则表达式越接近规范,它们将变得越大,因此,它们很难阅读和维护。下面,您将找到一些库中使用的更精确的正则表达式的示例。

⚠️以下正则表达式用于文档和学习目的,将其复制粘贴到您的代码中不是一个好主意。而是直接使用该库,因此您可以依靠上游代码和对等开发人员来使您的电子邮件解析代码保持最新并得到维护。

Perl地址匹配模块

此类正则表达式的最佳示例是某些语言的标准库。例如,RFC::RFC822::AddressPerl库中的模块中有一个试图根据RFC尽可能准确。为了您的好奇心,您可以在此URL上找到该正则表达式的版本,该版本是从语法生成的,如果您想复制粘贴,请参考正则表达式作者的报价:

我不维护正则表达式[链接]。可能其中的错误已在Perl模块中得到修复。

.Net地址匹配模块

另一个较短的变体是.Net标准库在EmailAddressAttribute模块中使用的变体:

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

但是,即使它更短,它仍然太大而无法阅读和易于维护。

Ruby地址匹配模块

在ruby中,正则表达式的组成在rfc822模块中用于匹配地址。这是一个好主意,因为如果发现错误,可以更轻松地找到正则表达式部分以进行更改和修复。

Python地址匹配模块

作为反例,python电子邮件解析模块未使用正则表达式,而是使用解析器实现了它。