跳转到主要内容
模块 8 · 第 1 课(共 4)课程中的29/32~12 min
模块课程(1/4)

验证电子邮件

“正确”验证电子邮件是一个比看起来更困难的问题: RFC 5322 是一个怪物。在实践中,我们选择一个“足够好”的模式 接受常见的情况,拒绝明显错误的情况。

Code
Pattern: ^[\w.+-]+@[\w-]+(?:\.[\w-]+)+$
  • [\w.+-]+ -- 本地部分:字母、数字、_、.、+、-。
  • @ -- 分隔符。
  • [\w-]+(?:\.[\w-]+)+ -- 域名 + 至少一个由 . 分隔的 TLD。

它接受:mario.rossi@example.com、foo+bar@sub.example.co.uk、 user_123@test-domain.io。

它拒绝:mario@、@example.com、mario@example(无 TLD)、空格。

权衡

上面的模式不接受:

  • 引用的字符串 "strange (things)"@example.com (RFC 允许)。
  • 具有 Unicode 字符的域 (\u00fcber@m\u00fcnchen.de)。
  • 未通过 \w 的超长 TLD(例如国际化 TLD)。

如果您需要它们,请使用 u 标志将类扩展到 \p{L} ,或委托给 专门图书馆。

电子邮件验证的权衡和最佳实践

任何正则表达式都不能保证电子邮件地址确实存在。过于复杂的模式会降低性能并排除异常但有效的域。最好使用简单的验证模式来拒绝明显的拼写错误并发送验证码。

尝试一下

锻炼#regex.m8.l1.e1
尝试:0加载中...

识别文本中的每封电子邮件。使用一种简单的模式:@ 之前的字母/数字/点,域中至少有一个点。

正在加载编辑器...
显示提示

将本地部分扩大到 [\\w.+-]+,将域扩大到 [\\w-]+\\.[\\w.-]+ 以接受多个 TLD。

3 次尝试后可用的解决方案

复习练习

锻炼#regex.m8.l1.e2
尝试:0加载中...

将每封电子邮件的域(@ 后面的部分)捕获为命名组“dominio”。

正在加载编辑器...
显示提示

将域部分包装在命名组中:(?<dominio>[\\w.-]+)。

3 次尝试后可用的解决方案

额外的挑战

锻炼#regex.m8.l1.e3
尝试:0加载中...

Find the domain part of an email (everything after `@`), excluding the `@` sign using lookbehind.

正在加载编辑器...
显示提示

在域字符类前面使用正向回顾 (?<=@)。

3 次尝试后可用的解决方案