
简介
正则表达式(regex)是用于匹配字符串中字符组合的模式。它们是文本处理、验证、搜索替换和数据提取的强大工具。本指南涵盖正则表达式基础、常见模式、测试策略和常见陷阱——所有内容均配有实际示例,您可以在我们的正则测试器中尝试。
正则基础
字面量和元字符
正则表达式模式由字面量(匹配自身的字符)和元字符(具有特定含义的特殊符号)组成。
| 模式 | 匹配内容 | 示例 |
|---|---|---|
hello |
字面字符串 "hello" | hello 在 "say hello" 中 |
. |
任意单个字符(除换行符) | h.t 匹配 "hat", "hot", "hut" |
\d |
任意数字(0-9) | \d{3} 匹配三位数字 |
\w |
任意单词字符(字母、数字、下划线) | \w+ 匹配一个单词 |
\s |
任意空白字符(空格、制表符、换行符) | \s 匹配一个空格 |
^ |
字符串开头 | ^Hello 匹配开头的 "Hello" |
$ |
字符串结尾 | world$ 匹配结尾的 "world" |
\b |
单词边界 | \bcat\b 匹配作为完整单词的 "cat" |
字符类
使用方括号 [...] 定义要匹配的字符集合。
[abc]匹配 'a', 'b' 或 'c'[a-z]匹配任意小写字母[0-9]匹配任意数字(同\d)[^abc]匹配除 'a', 'b', 'c' 之外的任意字符
量词
量词指定字符或组出现的次数。
| 量词 | 含义 | 示例 |
|---|---|---|
* |
0 次或多次 | ab*c 匹配 "ac", "abc", "abbc" |
+ |
1 次或多次 | ab+c 匹配 "abc", "abbc" 但不匹配 "ac" |
? |
0 次或 1 次 | colou?r 匹配 "color" 和 "colour" |
{n} |
恰好 n 次 | \d{3} 匹配恰好 3 位数字 |
{n,} |
n 次或更多 | \d{2,} 匹配 2 位或更多数字 |
{n,m} |
介于 n 和 m 之间 | \d{2,4} 匹配 2 到 4 位数字 |
分组和选择
- 分组:
(pattern)捕获匹配的子字符串。使用(?:pattern)进行非捕获分组。 - 选择:
|表示 OR。cat|dog匹配 "cat" 或 "dog"。
转义
要匹配字面元字符,使用反斜杠转义:\. 匹配点号,\* 匹配星号。
常见模式与用例
邮箱验证
一个简单的邮箱正则:^[\w.-]+@[\w.-]+\.\w{2,}$
^字符串开头[\w.-]+一个或多个单词字符、点号或连字符(本地部分)@字面 @[\w.-]+域名\.字面点号\w{2,}顶级域名(至少 2 个字母)$字符串结尾
URL 提取
从文本中提取 URL 的模式:https?://[\w./?=&-]+
密码强度
要求至少 8 个字符,包含一个大写字母、一个小写字母、一个数字:^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$
(?=.*[a-z])正向先行断言,确保有小写字母(?=.*[A-Z])正向先行断言,确保有大写字母(?=.*\d)正向先行断言,确保有数字.{8,}至少 8 个字符
去除多余空白
将多个空格替换为单个空格:\s+ → (单个空格)
实战示例:解析日志行
假设有如下日志行:
2025-03-21 14:23:45 ERROR User login failed: invalid password (user: jdoe)
2025-03-21 14:24:01 INFO User jdoe logged in successfully
您想提取时间戳、级别和消息。使用模式:
^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (\w+) (.*)$
^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})捕获时间戳(\w+)捕获日志级别(ERROR, INFO 等)(.*)$捕获消息的其余部分
在 JavaScript 中:
const log = "2025-03-21 14:23:45 ERROR User login failed: invalid password (user: jdoe)";
const regex = /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (\w+) (.*)$/;
const match = log.match(regex);
if (match) {
console.log("Timestamp:", match[1]);
console.log("Level:", match[2]);
console.log("Message:", match[3]);
}
输出:
Timestamp: 2025-03-21 14:23:45
Level: ERROR
Message: User login failed: invalid password (user: jdoe)
在我们的正则测试器中尝试此模式,查看高亮匹配。
测试策略
- 从简单开始:逐步构建模式,每添加一个部分都进行测试。
- 使用锚点:验证整个字符串时始终使用
^和$,避免部分匹配。 - 测试边界情况:空字符串、非常长的字符串、包含特殊字符的字符串。
- 使用正则测试器:视觉反馈有助于发现错误。我们的正则测试器提供实时匹配和解释。
- 考虑性能:尽可能使用占有量词或原子组,避免灾难性回溯。
常见陷阱
- 贪婪 vs. 懒惰:
.*是贪婪的(尽可能多地匹配)。使用.*?进行懒惰匹配。 - 字符串中的转义:在许多语言中,反斜杠需要转义(例如,JavaScript 字符串中的
\d)。 - Unicode 支持:
\w和\d可能不匹配非 ASCII 字符。使用 Unicode 属性转义如\p{L}匹配字母。 - 先行/后行断言:并非所有正则引擎都支持后行断言;请检查兼容性。
- 过于复杂的模式:有时简单的字符串方法更清晰、更快。
常见问题
贪婪量词和懒惰量词有什么区别?
贪婪量词(*, +, {n,m})尽可能多地匹配。懒惰量词(*?, +?, {n,m}?)尽可能少地匹配。例如,对于字符串 "<div>text</div>",/<.*>/ 匹配整个字符串,而 /<.*?>/ 只匹配 "<div>"。
如何匹配字面点号?
用反斜杠转义:\. 匹配句点。未转义的点号匹配任意字符。
什么是捕获组?
圆括号 (pattern) 创建一个捕获组,存储匹配的子字符串供以后使用。例如,/(\d+)-(\d+)/ 捕获由连字符分隔的两个数字。
如何测试正则表达式性能?
使用我们的正则测试器配合大输入字符串检查是否变慢。避免导致灾难性回溯的模式,例如在重叠模式上使用嵌套量词。
为什么我的正则表达式不匹配换行符?
默认情况下,点号 . 不匹配换行符。在大多数引擎中使用 s 标志(DOTALL)使 . 匹配换行符。