不要每次都从头写正则表达式。本指南提供了经过实战验证、可直接复制粘贴的正则模式,覆盖最常见的验证场景:邮箱地址、电话号码、URL、IP 地址、信用卡格式、日期、密码和用户名。每个模式都附带解释、边界情况说明,以及 JavaScript 和 Python 的代码示例。
如何使用这些模式
下面每个模式都显示在代码块中。直接将原始模式字符串复制到你的代码中即可。在 JavaScript 中,用正斜杠包裹 /pattern/ 或传递给 new RegExp()。在 Python 中,使用原始字符串 r"pattern" 配合 re.match() 或 re.fullmatch()。部署到生产环境前,务必针对有效和无效输入进行测试。
// JavaScript 快速开始
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
if (emailRegex.test(userInput)) {
console.log('有效邮箱');
}# Python 快速开始
import re
email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
if re.match(email_pattern, user_input):
print('有效邮箱')邮箱验证
邮箱验证是最常见的正则使用场景。没有任何单个正则能 100% 处理 RFC 5322,但以下模式覆盖了绝大多数真实邮箱地址。
基础邮箱模式
对大多数 Web 表单来说足够好。能捕获明显的拼写错误,同时不会过于严格。
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$匹配:user@example.com、john.doe+tag@sub.domain.org。不匹配:user@.com、@example.com、user@com。
RFC 5322 兼容(简化版)
更全面的模式,能处理带引号的本地部分和较长的 TLD。仍然不是 100% RFC 兼容(完整的 RFC 5322 正则超过 6,000 个字符),但覆盖了基础模式遗漏的边界情况。
^(?:[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$仅限常见域名
当你想限制为知名邮箱提供商时(例如消费者注册表单)。
^[a-zA-Z0-9._%+-]+@(gmail|yahoo|outlook|hotmail|icloud|protonmail)\.[a-z]{2,}$电话号码验证
电话号码格式因国家/地区而异。以下模式可作为起点,根据你的目标地区进行调整。
美国电话号码
匹配带或不带国家代码的常见美国格式。
^(\+1[-\s.]?)?\(?[2-9]\d{2}\)?[-\s.]?\d{3}[-\s.]?\d{4}$匹配:+1 (555) 123-4567、555-123-4567、5551234567、+1.555.123.4567。
国际电话号码
通用模式,允许国家代码和各种分隔符。
^\+?[1-9]\d{0,2}[-\s.]?\(?\d{1,4}\)?[-\s.]?\d{1,4}[-\s.]?\d{1,9}$E.164 格式(严格)
国际电话号码标准。被 Twilio、Stripe 和大多数 API 使用。
^\+[1-9]\d{1,14}$匹配:+14155552671、+442071234567。总共最多 15 位数字(包括国家代码)。
URL 验证
URL 验证可简可繁。选择适合你需求的模式。
HTTP/HTTPS URL
要求 http 或 https 协议前缀。
^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$有无协议均可的 URL
匹配可能省略 http:// 或 https:// 的 URL。
^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([\/\w .-]*)*\/?$Localhost URL
用于开发环境——匹配 localhost 及可选端口和路径。
^https?:\/\/(localhost|127\.0\.0\.1)(:\d{1,5})?(\/[^\s]*)?$匹配:http://localhost:3000/api、https://127.0.0.1:8080。
IP 地址验证
IP 地址验证需要仔细检查每个八位组(IPv4)或组(IPv6)的范围。
IPv4 地址
验证每个八位组在 0 到 255 之间。
^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.){3}(25[0-5]|(2[0-4]|1\d|[1-9]|)\d)$匹配:192.168.1.1、10.0.0.255。拒绝:256.1.1.1、192.168.1。
IPv6 地址(简化版)
标准 IPv6 表示法的简化模式。完整的 IPv6 验证(含 :: 缩写)极为复杂。
^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$IPv6 地址(完整版含 :: 缩写)
处理大多数真实 IPv6 地址中使用的 :: 零压缩表示法。
^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$IP 地址带端口
IPv4 地址后跟可选端口号(1-65535)。
^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.){3}(25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(:(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}))?$信用卡号码模式
重要提示:这些模式仅验证格式(正确的位数和前缀),不能验证卡号是否真实。除了正则外,务必使用 Luhn 算法进行校验和验证。
Visa
^4[0-9]{12}(?:[0-9]{3})?$以 4 开头。13 或 16 位数字。
MasterCard
^5[1-5][0-9]{14}$|^2(?:2(?:2[1-9]|[3-9]\d)|[3-6]\d\d|7(?:[01]\d|20))[0-9]{12}$以 51-55 或 2221-2720 开头。始终 16 位数字。
American Express
^3[47][0-9]{13}$以 34 或 37 开头。始终 15 位数字。
所有主要卡种(组合)
^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12})$涵盖 Visa、MasterCard、AMEX、Diners Club 和 Discover。
日期格式模式
这些模式验证日期的格式。对于实际日期有效性(例如 2 月 30 日),还需要使用日期库进行验证。
YYYY-MM-DD(ISO 8601)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$匹配:2026-01-15、2026-12-31。拒绝:2026-13-01、2026-00-10。
MM/DD/YYYY
^(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])\/\d{4}$DD.MM.YYYY
^(0[1-9]|[12]\d|3[01])\.(0[1-9]|1[0-2])\.\d{4}$在德国、瑞士及其他欧洲国家常用。
密码强度验证
使用前瞻断言在单个模式中强制执行多项要求。根据你的安全策略调整最小长度和字符要求。
强密码(至少 8 个字符,含大写、小写、数字、特殊字符)
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$至少需要:1 个小写字母、1 个大写字母、1 个数字、1 个 @$!%*?& 中的特殊字符,总长度至少 8 个字符。
中等密码(至少 6 个字符,字母 + 数字)
^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$自定义长度范围(8-64 个字符,全部要求)
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\w\s]).{8,64}$[^\w\s] 字符类匹配任何特殊字符(比特定列表更广泛)。
用户名验证
用户名模式为用户标识符强制执行一致的格式。
字母数字 + 下划线(3-16 个字符)
^[a-zA-Z0-9_]{3,16}$必须以字母开头
^[a-zA-Z][a-zA-Z0-9_]{2,15}$允许点和连字符(不连续)
^[a-zA-Z0-9](?:[a-zA-Z0-9._-]*[a-zA-Z0-9])?$必须以字母数字开头和结尾。不允许连续的点/连字符。类似于 GitHub 用户名规则。
对比表:所有模式一览
使用此速查表找到适合你用例的正确模式。
| Use Case | Pattern | Notes |
|---|---|---|
| Email (basic) | ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ | Most web forms |
| Phone (US) | ^(\+1[-\s.]?)?\(?[2-9]\d{2}\)?[-\s.]?\d{3}[-\s.]?\d{4}$ | Multiple formats |
| Phone (E.164) | ^\+[1-9]\d{1,14}$ | API standard |
| URL (HTTP/S) | ^https?:\/\/[^\s]+$ | Quick check |
| IPv4 | ^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.){3}(25[0-5]|(2[0-4]|1\d|[1-9]|)\d)$ | 0-255 per octet |
| IPv6 (simple) | ^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$ | No :: shorthand |
| Visa | ^4[0-9]{12}(?:[0-9]{3})?$ | 13 or 16 digits |
| MasterCard | ^5[1-5][0-9]{14}$ | 16 digits |
| AMEX | ^3[47][0-9]{13}$ | 15 digits |
| Date (ISO) | ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$ | YYYY-MM-DD |
| Date (US) | ^(0[1-9]|1[0-2])\/(0[1-9]|[12]\d|3[01])\/\d{4}$ | MM/DD/YYYY |
| Date (EU) | ^(0[1-9]|[12]\d|3[01])\.(0[1-9]|1[0-2])\.\d{4}$ | DD.MM.YYYY |
| Strong Password | ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$ | All requirements |
| Username | ^[a-zA-Z][a-zA-Z0-9_]{2,15}$ | Letter start, 3-16 chars |
测试你的正则
在生产环境使用前,务必针对有效和无效输入测试正则模式。
JavaScript 测试
// 方法 1: RegExp.test() - 返回布尔值
const pattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
console.log(pattern.test('user@example.com')); // true
console.log(pattern.test('invalid@')); // false
// 方法 2: String.match() - 返回匹配数组或 null
const result = 'user@example.com'.match(pattern);
if (result) {
console.log('匹配:', result[0]);
}
// 方法 3: String.matchAll() - 使用 /g 标志获取多个匹配
const text = '联系我们 info@test.com 或 help@test.com';
const emailPattern = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
for (const m of text.matchAll(emailPattern)) {
console.log('找到:', m[0]);
}Python 测试
import re
# 方法 1: re.match() - 从字符串开头匹配
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
result = re.match(pattern, 'user@example.com')
print(bool(result)) # True
# 方法 2: re.fullmatch() - 匹配整个字符串 (Python 3.4+)
result = re.fullmatch(pattern, 'user@example.com')
print(bool(result)) # True
# 方法 3: re.findall() - 查找所有匹配
text = '联系我们 info@test.com 或 help@test.com'
emails = re.findall(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', text)
print(emails) # ['info@test.com', 'help@test.com']
# 方法 4: 编译模式(重复使用时最佳)
email_re = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
for addr in ['valid@test.com', 'bad@', 'ok@domain.org']:
print(f'{addr}: {bool(email_re.match(addr))}')在线测试工具
要进行交互式、可视化的正则测试,请使用我们的 Regex 测试器工具。你也可以使用 regex101.com 或 regexr.com 获取详细分析。我们的工具支持 JavaScript 正则语法和实时高亮显示。
常见问题
应该使用正则验证邮箱吗?
正则是客户端邮箱验证的优秀初步过滤器。它能在表单提交前捕获明显的拼写错误(缺少 @、没有域名等)。然而,真正验证邮箱的唯一方法是向其发送确认邮件。使用基础正则模式改善用户体验,用验证邮件确保正确性。
为什么有这么多不同的邮箱正则模式?
邮箱规范(RFC 5322)非常宽松——它允许引号字符串、注释、IP 地址域和不常见的字符。一个完全兼容的正则会有数千个字符长,不切实际。大多数开发者使用简化模式,覆盖 99.9% 的真实邮箱地址。根据你需要的严格程度选择模式。
正则能验证电话号码是否真实存在吗?
不能。正则只能验证格式(正确的位数、有效的国家代码前缀、正确的分隔符)。它无法验证号码是否分配给了真实线路。对于生产环境的电话验证,请使用 libphonenumber(Google)等库,它具有按国家/地区的规则和运营商验证。
如何验证带 :: 缩写的 IPv6 地址?
带 :: 缩写(零压缩)的 IPv6 用正则验证非常困难,因为 :: 可以出现在任何位置,并替代一个或多个零组。本指南中的完整模式处理了大多数情况。对于生产系统,考虑使用语言内置的 IP 解析(例如 Python 的 ipaddress 模块、Node.js 的 net.isIP())而非正则。
用正则做密码强度验证安全吗?
是的,使用前瞻断言的正则是强制执行密码复杂度规则(最小长度、必需字符类型)的高效方式。然而,密码强度不仅仅是字符多样性——还应考虑检查泄露密码数据库(如 HaveIBeenPwned)和使用基于熵的评分。正则处理格式规则,将其与额外的安全检查配合使用。