如何使用正则表达式验证电子邮件地址

如何使用正则表达式验证电子邮件地址

技术背景

在软件开发中,验证电子邮件地址的有效性是一个常见需求,如表单验证、数据清洗等。虽然可以通过发送确认邮件来验证地址的实际有效性,但在前期使用正则表达式进行初步的语法验证可以提高效率和用户体验。电子邮件地址的语法规则由多个RFC(Request for Comments)文档定义,如RFC 822和RFC 5322 ,后续的标准对语法进行了进一步限制。

实现步骤

1. 选择合适的RFC标准

  • RFC 822:是早期的标准,语法较为宽松。对应的正则表达式为:
1
([^][()<>@,;:\" . \x00-\x1F\x7F]+|"(\n|(\\\r)*([^\"\r\n]|\\[^\r]))*(\\\r)*")(\.([^][()<>@,;:\" . \x00-\x1F\x7F]+|"(\n|(\\\r)*([^\"\r\n]|\\[^\r]))*(\\\r)*"))*@([^][()<>@,;:\" . \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\r\n]|\\[^\r]))*(\\\r)*])(\.([^][()<>@,;:\" . \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\r\n]|\\[^\r]))*(\\\r)*]))*
  • RFC 5322:是当前的标准,语法更为严格。对应的正则表达式为:
1
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])

2. 考虑进一步限制

  • SMTP限制:RFC 5321对电子邮件地址有进一步限制,特别是在域名部分。对应的正则表达式为:
1
([-!#-'*+/-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^-~]+)])
  • 用户输入验证:对于用户输入验证,通常可以排除地址字面量,并要求主机名至少有两个标签。对应的正则表达式为:
1
([-!#-'*+/-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])?)+

3. 选择编程语言和工具

不同编程语言对正则表达式的支持略有不同,但基本语法相似。以下是一些常见语言的示例:

JavaScript

1
2
3
4
5
6
7
const email = '[email protected]';
const regex = /^([-!#-'*+/-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])?)+$/;
if (regex.test(email)) {
console.log('Valid email address');
} else {
console.log('Invalid email address');
}

Python

1
2
3
4
5
6
7
8
import re

email = '[email protected]'
regex = r'^([-!#-\'*+/-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])?)+$'
if re.match(regex, email):
print('Valid email address')
else:
print('Invalid email address')

核心代码

以下是几种不同场景下的正则表达式核心代码:

简单验证

1
/.+@[^@]+\.[^@]{2,}$/

RFC 5322 规范验证

1
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])

用户输入验证

1
([-!#-'*+/-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])?)+

最佳实践

  • 结合发送确认邮件:正则表达式只能验证语法,不能验证地址的实际有效性。因此,在初步验证后,最好发送确认邮件来确保地址可使用。
  • 选择合适的正则表达式:根据具体需求选择合适的正则表达式,如仅进行简单验证可使用简单的正则表达式,如进行严格验证则使用符合RFC标准的正则表达式。
  • 定期更新正则表达式:随着新的顶级域名的出现和RFC标准的更新,需要定期更新正则表达式以确保其有效性。

常见问题

  • 正则表达式过于复杂:一些符合RFC标准的正则表达式非常复杂,难以理解和维护。可以选择简单的正则表达式进行初步验证,或者使用现有的验证库。
  • 无法处理所有情况:即使使用最严格的正则表达式,也可能无法处理所有合法的电子邮件地址。因此,最终还是需要通过发送确认邮件来验证地址的有效性。
  • 性能问题:复杂的正则表达式可能会影响性能。在处理大量数据时,需要考虑性能问题,可以选择优化正则表达式或使用其他验证方法。

如何使用正则表达式验证电子邮件地址
https://119291.xyz/posts/2025-05-09.how-to-validate-email-address-with-regex/
作者
ww
发布于
2025年5月9日
许可协议