我听说用正则表达式验证电子邮件地址是一件不好的事情,实际上会引起危害。为什么会这样呢?
我曾认为验证数据永远不可能是一件坏事,也许是没有必要的,但只要你正确地执行验证,就绝不会有问题。这个做法到底对还是错呢?如果会造成危害,请给出一个例子。
我听说用正则表达式验证电子邮件地址是一件不好的事情,实际上会引起危害。为什么会这样呢?
我曾认为验证数据永远不可能是一件坏事,也许是没有必要的,但只要你正确地执行验证,就绝不会有问题。这个做法到底对还是错呢?如果会造成危害,请给出一个例子。
通常情况下,使用正则表达式验证电子邮件地址是有害的。这是由于正则表达式作者做出了错误的假设。
正如klutt所指出的,电子邮件地址包含两个部分:local-part
和domain
。值得注意的是,关于这些部分的一些事情并不立即显而易见:
local-part
可以包含转义字符甚至额外的@
字符。local-part
可能区分大小写,但具体是由该特定域名的邮件服务器决定如何区分大小写。domain
部分可以包含零个或多个标签,由句点(.
)分隔,尽管实际上没有对应于根(零标签)或TLD(一个标签)本身的MX记录。因此,在不拒绝与上述相对应的有效电子邮件地址的情况下,您可以进行一些检查:
@
local-part
(右侧最后一个@
之前的所有内容)不为空domain
部分(右侧最后一个@
之后的所有内容)包含至少一个句点(再次,这并不严格正确,但很实用)就是这样。正如其他人所指出的,最佳实践是测试该地址的可交付性。这将建立两个重要的事情:
如果将电子邮件激活过程纳入业务流程中,则无需担心具有问题的复杂正则表达式。
进一步阅读:
rogue+somesecretthing@abc.xyz
,我决定不在不允许 +
的网站上注册的次数已经不止一次了。 - Rogue除非你有充分的理由使用正则表达式验证电子邮件,否则不要使用它们。最好使用验证邮件来进行验证。在大多数情况下,一个简单检查字符串是否包含@符号的正则表达式就足够了。
在大多数情况下,问题“如何使用正则表达式验证电子邮件地址”很可能是一个XY问题,因为它很可能不是解决您实际问题的方法。真正的问题可能是“如何确保用户输入的电子邮件地址可以用于与用户进行通信?”或者正如zsalya在评论中提到的,“在将用户输入的电子邮件地址存储到数据库之前,应该对其进行哪些净化处理?”
构建用于验证电子邮件的正则表达式可以是一项有趣且有益的练习,但通常情况下,在生产代码中应该尽量避免使用它。验证电子邮件地址的正确方法在大多数情况下是发送验证邮件。试图验证邮件地址是否符合规范非常棘手,即使你做对了,这仍然经常是无用的信息,除非你知道它是一个可以发送邮件并且有人会阅读的邮件地址。.+@.+\..+
还有一件事,即使你完全正确,可能仍然不足够。电子邮件地址在@符号左侧具有本地部分,在右侧具有域名部分。本地部分的所有内容都应由服务器处理。当然,RFC 5322对有效的本地部分的要求非常详细,但是如果特定的电子邮件服务器接受不符合RFC 5322的地址,那该怎么办?您真的确定不想允许一个有效的电子邮件地址,只因为它不遵循标准吗?您是否愿意因为客户选择了一个不常见的电子邮件供应商而失去业务?或者因为您在正则表达式中犯了一个错误?(提示:使用特定语言字符时很容易出错)
我在这里可以补充一下,我曾经因为我的电子邮件地址无法注册到各种网站。而且我的地址并不奇怪。它只是简单的<name>@protonmail.com
,但有些网站声称它不是有效的地址。我很难相信这是因为<name>
,因为它只包含来自a-z的12个小写字母。
Mailaddress
类这样的方法来验证电子邮件地址可以提供一些保护,防止恶意输入,比如SQL注入等。但如果这是你唯一的防范恶意输入的方法,那么你肯定在其他方面做错了什么。如果您的正则表达式格式不正确,则可能会拒绝有效的电子邮件地址。这适用于任何“电子邮件验证”规则。
我知道有一个常常被拒绝的电子邮件地址,它没有任何奇怪之处,只是很长而已。因为 @
前面的部分是他们的法定名称,所以它真的让这个人很烦恼——在电子邮件地址方面显然是一个明显的选择。
这是错误地进行电子邮件验证的潜在危害的一部分:通过拒绝输入系统中的有效电子邮件地址来使用户感到困扰。
验证数据并不是坏事。但是在这种情况下,您将为应用程序提供一个设计有缺陷的功能:
对于开发人员来说,您的应用程序似乎正在验证输入,但验证可能是不必要的、可能不完整的,并且在验证结束时,您不知道是否有一个地址可以让您联系用户。
也许是不必要的,但只要正确执行验证,就永远不会是坏事。
它不是不必要的;它是必要的。只是正则表达式是错误的工具。
归根结底,检查地址是否对用户有效的最佳方法是使用唯一令牌交换该地址:
正则表达式可能是验证电子邮件地址的最佳方法,只要您使用正确的表达式。一旦您使用正则表达式检查了地址,只需要检查几个附加要求(地址不太长且有效的UTF-8编码)。
这是因为定义电子邮件地址格式的ABNF语法是“正则”的,这意味着它可以被描述为一个正则表达式;没有回溯、递归或任何非正则特征。
这只是理解规范的问题;但一旦您理解了规范,就会发现电子邮件地址的正则表达式实际上非常简单:如何使用正则表达式验证电子邮件地址?
正则表达式并不会造成伤害。
使用一个好的电子邮件正则表达式来过滤那些急躁的虚假用户。
如果你要向那个人销售产品,你可能需要联系他们进行进一步验证,尽管卖家并不太关心电子邮件,只要验证信用卡就足够了。
否则,唯一需要验证的地方就是当有人想要访问和与你的论坛互动时,而你希望通过将他们的电子邮件出售给大规模广告商来获得报酬,即使你说你不会这样做。
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])?)*$
http://www.w3.org/TR/html5/forms.html#valid-e-mail-address
^
[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]
)?
)*
$