alltools.one
Development
2025-06-15
7 min
alltools.one Team
RegexEmailValidationJavaScriptDevelopment

邮箱验证的正则表达式:真正有效的模式

邮箱验证是最常见的正则表达式用例之一——也是最容易被误解的用例之一。RFC 5321 电子邮件地址规范非常复杂,没有任何单一正则表达式能完全验证它。但是,覆盖 99.9% 真实电子邮件地址的实用模式既可实现又有用。

简单模式(足够好用)

对于大多数应用程序,以下模式效果良好:

^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

匹配内容:一个或多个允许的字符,后跟 @,再后跟一个至少包含一个点和 2+ 字母顶级域名的域名。

JavaScript:

const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
emailRegex.test('user@example.com');  // true
emailRegex.test('user@.com');          // false

使用我们的正则表达式测试器测试此模式。

为什么完美的正则验证不可能

电子邮件规范(RFC 5321/5322)允许一些有效但在实践中几乎从未使用的结构:

"john..doe"@example.com           // Quoted local part with consecutive dots
user@[192.168.1.1]                // IP address as domain
"very.(),:;<>[]\".VERY."very@\ "very".unusual"@strange.example.com

处理所有 RFC 有效地址的正则表达式长达数千个字符,仍可能无法覆盖每个边界情况。实用的方法是:使用简单的正则进行基本格式验证,然后通过发送确认邮件来验证邮箱是否真实存在。

模式分解

本地部分(@ 之前)

[a-zA-Z0-9._%+-]+
  • 字母(大小写)
  • 数字
  • 点、下划线、百分号、加号、连字符
  • 一个或多个字符

常见错误

  • 允许开头或结尾出现点(技术上无效)
  • 允许连续的点(没有引号时技术上无效)
  • 过于严格(阻止了有效字符如 Gmail 别名使用的 +

域名部分(@ 之后)

[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
  • 字母数字字符、点、连字符
  • 至少一个点
  • 2+ 个字母的顶级域名

常见错误

  • 将顶级域名长度限制为 3-4 个字符(.museum.photography 确实存在)
  • 不允许域名中的连字符
  • 不处理子域名(user@mail.example.co.uk

更好的模式

HTML5 标准

HTML5 规范为 <input type="email"> 定义了以下模式:

^[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])?)*$

这个模式在本地部分更宽松,在域名标签长度方面更严格。

推荐的实用模式

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

这个最小化模式简单地确保:没有空格、一个 @@ 后至少一个点、2+ 个字符的顶级域名。它有意设计得很宽松——拦截明显错误的输入,而不拒绝不常见但有效的地址。

各语言实现

JavaScript

function isValidEmail(email) {
  // Basic regex check
  const regex = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/;
  if (!regex.test(email)) return false;
  
  // Additional checks
  if (email.length > 254) return false;  // RFC 5321 limit
  const [local] = email.split('@');
  if (local.length > 64) return false;   // RFC 5321 limit
  
  return true;
}

Python

import re

def is_valid_email(email: str) -> bool:
    pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
    if not re.match(pattern, email):
        return False
    if len(email) > 254:
        return False
    local, domain = email.rsplit('@', 1)
    if len(local) > 64:
        return False
    return True

超越正则:正确的邮箱验证

正则只是第一道防线。完整的验证策略:

  1. 格式检查(正则):拒绝明显无效的格式
  2. 长度检查:本地部分 ≤ 64 字符,总长度 ≤ 254 字符
  3. DNS 检查:验证域名是否有 MX 记录
  4. 一次性邮箱检测:必要时阻止临时邮箱服务
  5. 确认邮件:真正验证邮箱的唯一方法——发送一封邮件并确认用户收到
// DNS MX record check (Node.js)
const dns = require('dns');
const [, domain] = email.split('@');
dns.resolveMx(domain, (err, addresses) => {
  if (err || !addresses.length) {
    console.log('Domain has no email server');
  }
});

需要避免的常见错误

  1. 过于严格的模式:阻止 user+tag@gmail.com(加号寻址)或 user@subdomain.example.com
  2. 区分大小写:根据 RFC,邮箱本地部分可以区分大小写,但实际上应视为不区分大小写
  3. 去除空白:验证前始终去除空白字符 — " user@example.com " 应该通过
  4. 国际化域名.münchen用户@例え.jp 在国际化电子邮件中是有效的

更多正则表达式模式,请参阅我们的正则表达式速查表

常见问题

应该在客户端还是服务器端用正则验证邮箱?

两者都要。客户端验证提供即时反馈(更好的用户体验)。服务器端验证对于安全性是必须的(客户端检查可以被绕过)。永远不要仅依赖客户端验证。

为什么有些网站拒绝我的有效邮箱地址?

过于严格的正则模式通常是原因。带 + 的地址(Gmail 别名)、长顶级域名(.technology)或子域名经常被糟糕的验证拒绝。如果你维护一个网站,请使用宽松的正则表达式,并通过确认邮件进行验证。

相关资源

Published on 2025-06-15
Regex for Email Validation: Patterns That Actually Work | alltools.one