此电子邮件验证正则表达式中不可打印控制字符的用途是什么?

jmo*_*253 5 regex email email-validation node.js sonarqube

背景资料

\n

我们使用 SonarQube 来获取有关代码库的质量指标。SonarQube 根据规则S6324在我们的 Node.js 代码库中标记了十多个错误,这些错误与 Google 上排名靠前的网站emailregex.com提倡的电子邮件验证正则表达式相关。该网站声称该正则表达式是 RFC 5322 官方标准。但是,正则表达式中的控制字符被 SonarQube 标记为要删除,因为它们是不可打印的字符。这是正则表达式:

\n
(?:[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])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-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])+)\\])\n
Run Code Online (Sandbox Code Playgroud)\n

以下是 SonarQube 抱怨的控制字符的完整列表:\n\xe2\x80\x98.\\x0e\xe2\x80\xa6\\x0e\xe2\x80\xa6\\x0c\xe2\x80\xa6\\x0c\xe2\x80\xa6\\x0b\xe2\x80\xa6\\x0c\xe2\x80\xa6\\x1f\xe2\x80\xa6\\x01\xe2\x80\xa6\\x1f\xe2\x80\xa6\\x01\xe2\x80\xa6\\x01\xe2\x80\xa6\\x09\xe2\x80\xa6\\x08\xe2\x80\xa6\\x0b\xe2\x80\xa6\\x0b\xe2\x80\xa6\\x0e\xe2\x80\xa6\\x0b\xe2\x80\xa6\\x08\xe2\x80\xa6\\x0c\xe2\x80\xa6\\x0e\xe2\x80\xa6\\x09\xe2\x80\xa6\\x01.\xe2\x80\x99

\n

Regular-Expressions.info\ 的电子邮件页面确实解决了上述正则表达式的变体,如下所示:

\n
\n

您不应该\xe2\x80\x99t 使用此正则表达式的原因是它过于广泛。您的应用程序可能无法处理此正则表达式允许的所有电子邮件地址。域特定的路由地址可以包含不可打印的 ASCII 控制字符,如果您的应用程序需要显示地址,这可能会导致麻烦...

\n
\n

但是,我似乎找不到任何信息来解释为什么某些站点添加这些不可打印的控制字符或“特定于域的路由地址”的含义。我查看了一些Stack Overflow 正则表达式问题Stack Overflow Regex Wiki。控制字符似乎没有被解决。

\n

问题

\n

有人可以解释一下正则表达式中这些控制字符的用途,并可能提供一些该正则表达式何时有用的示例吗?

\n

(注意:请避免关于验证电子邮件的最佳/最差正则表达式是什么的争论/讨论。在这个问题上似乎没有达成一致,这个问题已经在 Stack Overflow 和更广泛的互联网上的许多地方进行了讨论和辩论本题重点是理解正则表达式中控制字符的用途)。

\n

更新

\n

我也联系了 SonarQube 社区,但似乎没有人有任何答案

\n

更新

\n

仍在寻找权威答案,以解释为什么上面的电子邮件正则表达式专门检查电子邮件地址中的不可打印控制字符。

\n

RFC5322 第 5 节中有这样的内容,但它是关于消息正文,而不是地址:

\n
\n
    \n
  1. 安全考虑
  2. \n
\n

在终端或终端模拟器上显示消息时需要小心。\n 功能强大的终端可以对转义序列和 US-ASCII 控制字符的其他组合进行操作,并产生各种后果。他们可以重新映射键盘或允许对终端进行其他\n修改,这可能导致拒绝服务甚至损坏数据。它们可以触发(有时是可编程的)

\n
\n

sta*_*all 10

目的

有人可以解释一下正则表达式中这些控制字符的用途吗?

这些不可打印控制字符的目的是创建一个严格符合定义电子邮件地址格式的 RFC 的正则表达式。

以防万一有人想知道 - 是的 - 此电子邮件正则表达式中的控制字符确实符合RFC 规范。我认为验证这一点超出了这个问题的范围,所以我不会详细引用规范,但这里有相关部分的链接:3.2.3(原子)3.2.4(引用的字符串)3.4(地址规范) )3.4.1(addr-spec 规范)4.1(杂项过时令牌)。总之,地址的本地部分和域部分允许包含带引号的字符串,允许包含某些不可打印的控制字符。

引用SonarQube 规则 S6324(添加强调):

ASCII 表中代码 32 以下的条目称为控制字符或非打印字符。由于它们在 JavaScript 字符串中并不常见,因此在正则表达式中使用这些不可见字符很可能是一个错误。

遵循规范并不是一个错误。当通常有用的 lint 规则遇到人们代码中没有帮助的情况时,人们通常只是使用 lint 工具的逐个案例忽略机制。我认为这解决了赏金的第二条,其中规定:

有什么更好的替代方案可以避免破坏我们的网站,同时还能通过 SonarQube 的质量门?

IE。使用提供的机制之一使 SonarQube 忽略这些违反规则的行为。您也可以选择完全不检查该规则,但这可能有点矫枉过正。

对于 SonarQube,使用NOSONAR注释根据具体情况禁用警告。

有用的例子

这取决于具体情况。

如果您的最终目标纯粹是验证任何给定的电子邮件地址是否是 RFC 定义的有效电子邮件地址,那么严格遵循 RFC 规范的正则表达式非常有用。

这不是每个人的最终目标。引用维基百科

尽管技术上有效的特殊字符范围很广,但实际上组织、邮件服务、邮件服务器和邮件客户端通常并不接受所有这些字符。例如,Windows Live Hotmail 仅允许使用字母数字、点 (.)、下划线 (_) 和连字符 (-) 创建电子邮件地址。常见的建议是避免使用一些特殊字符,以避免电子邮件被拒绝的风险。

没有任何东西可以解释为什么大多数应用程序不完全遵守规范,但您可以推测,或者您可以尝试询问他们的维护人员。例如,在某些人的背景下,诸如简单性之类的考虑因素可能会被声明或视为比完全遵守 RFC 更重要。

如果您的目标是检查给定电子邮件地址是否是有效的hotmail电子邮件地址,并拒绝 RFC 允许但 hotmail 使用的子集不允许的电子邮件地址,则不需要完全遵守 RFC 有用)。