Appearance
正则表达式完全教程
Written/Drawn by claude-opus-4.7
1. 它到底是什么?
「正则表达式」是一种用一小段「模式」去描述一类文本的写法。
举个对比:
- 普通查找:你输入
apple,它去找文本里那一串字符。 - 正则查找:你输入
\d+,它会找出文本里所有连续的数字——可能是42、也可能是1024,长度不限。
你可以把它理解为「带通配规则的查找」,并且这种查找:
- 能找出很多位置;
- 能找出结构(比如「日期」「邮箱」「URL」);
- 能配合替换,做批量改写。
2. 第一个例子
直接看一个完整的「查找 + 替换」例子。
| 项目 | 内容 |
|---|---|
| 输入文本 | 今天是 2026-05-17 |
| 搜索(正则) | \d{4}-\d{2}-\d{2} |
| 匹配到 | 2026-05-17 |
| 替换为 | 〔已隐藏日期〕 |
| 替换后 | 今天是 〔已隐藏日期〕 |
只要你能看懂这一步,本教程前 80% 就一半学会了。下面把每个符号慢慢讲清楚。
3. 基础语法
3.1 字面量匹配
最简单的正则,就是「自己」。
绝大多数普通字符(字母、数字、汉字)写出来就代表它字面上的样子。 只有少数符号有特殊含义,它们叫元字符:
. * + ? ^ $ | \ ( ) [ ] { }要匹配它们本身,需要在前面加 \ 转义(见 3.9)。
3.2 通配符 .
. 表示「任意一个字符」(默认不含换行符)。
要点:
.一次只代表 1 个字符;- 想匹配字面的「点」要写
\.。
3.3 字符类 [ ] 与否定 [^ ]
用方括号列出一个候选清单,匹配里面的任意一个字符。在最前面加 ^ 就表示「不是这些字符」。
支持「范围」简写:
| 写法 | 含义 |
|---|---|
[0-9] | 任意数字 |
[a-z] | 任意小写字母 |
[A-Z] | 任意大写字母 |
[a-zA-Z0-9_] | 字母、数字、下划线 |
在
[ ]里,大部分元字符(.*+等)都会失去特殊含义,写出来就是字面意义。需要小心的只有]\^-。
3.4 预定义字符类 \d \w \s …
为了不每次都写 [0-9],正则提供了一组「缩写」:
| 缩写 | 等价于 | 含义 |
|---|---|---|
\d | [0-9] | 数字 |
\D | [^0-9] | 非数字 |
\w | [A-Za-z0-9_] | 单词字符 |
\W | [^A-Za-z0-9_] | 非单词字符 |
\s | 空白字符 | 空格、Tab、换行等 |
\S | 非空白字符 |
记忆口诀:大写 = 「非」。
可以用
[\s\S]代表任意字符(相当于一个集合加上它的非集等于全集)。
3.5 量词 * + ? {n,m}
量词写在「某个东西」后面,表示这个东西出现几次。
| 写法 | 含义 | 例子 | 匹配 |
|---|---|---|---|
? | 0 次 或 1 次 | colou?r | color、colour |
* | 0 次 或 更多 | a* | 空串、a、aa、… |
+ | 1 次 或 更多 | \d+ | 42、1024 |
{n} | 恰好 n 次 | \d{4} | 2026 |
{n,} | 至少 n 次 | \d{2,} | 12、123、… |
{n,m} | n 到 m 次 | \d{2,4} | 12、123、1234 |
记忆口诀:? = 可有可无;+ = 至少一个;* = 来不来都行。
3.6 锚点 ^ 与 $
它们不匹配任何字符,只表示「位置」:^ = 开头,$ = 结尾。
^abc$ 就表示「整段必须正好等于 abc」。
3.7 单词边界 \b
\b 也是一个位置:在「单词字符」和「非单词字符」之间的那条缝。
用它可以避免「子串误伤」。
3.8 选择
竖线 | 表示「或」,匹配几种可能中的任意一种。
也可以配合分组限定范围,比如 gr(a\|e)y 表示 gray 或 grey。
3.9 转义 \
把元字符变回普通字符,就在它前面加 \:
| 想匹配 | 写法 |
|---|---|
. | \. |
* | \* |
( | \( |
\ | \\ |
| | \| |
4. 分组与捕获
4.1 普通捕获组 ( )
圆括号有两个作用:
- 分组:让里面的内容作为一个整体接受量词、选择等操作;
- 捕获:记录下匹配到的文本,之后可以引用(用于替换、反向引用)。
捕获组从左到右,按 ( 的出现顺序编号:第 1 个是 $1、第 2 个是 $2,依此类推;$0 表示整体匹配。
4.2 非捕获组 (?: )
如果你只想「分组」不想「捕获」(不占编号、避免编号错位、稍微更快),用 (?:...):
(?:https?):// 匹配 http:// 或 https://,但 https/http 这一组不进编号。
4.4 反向引用
在同一个正则里再次引用前面捕获到的内容,用 \1、\2…
\1 的意思是「和第 1 组捕获到的字符一模一样」——非常适合查重复字、重复词。 命名版本:\k<name>。
5. 替换
正则的另一半威力,是替换。绝大多数编辑器、聊天工具、本项目的「正则库」功能都用同一套写法。
5.1 基础替换
如果替换字符串里没有特殊符号,它就照原样写入。
5.2 引用整体匹配 $0
$0 代表「这一次匹配到的全部内容」。
部分工具也支持
$&作为$0的别名。
5.3 引用捕获组 $1…$9
最常用的能力:重新组装文本。
也可以重复使用、可以混入字面文本:
如果要写字面的
$,使用$$:例如「金额 $$$1」会得到「金额 $42」。
5.5 在开头/结尾插入
^ 和 $ 本身不消费任何字符,但它们是真实的位置——所以可以「替换」它们,效果就是「在那个位置插入文本」。
5.6 综合替换案例
| 目的 | 搜索 | 替换为 |
|---|---|---|
| 全角逗号换半角并加空格 | , | , |
| 给中文数字加注释 | ([一二三四五六七八九十]+) | $1(中文数字) |
| 删除 Markdown 链接外壳 | \[([^\]]+)\]\([^)]+\) | $1 |
key=value 改 JSON 键值对 | (\w+)=(\w+) | "$1": "$2" |
6. 贪婪 vs 懒惰
量词默认是「贪婪」的:能多吃就多吃。在量词后加一个 ?,它就变成「懒惰」:够用就停。
懒惰量词:*?、+?、??、{n,m}?。
经验法则:「找夹在两个东西中间的东西」时,几乎总是用懒惰。
7. 进阶:断言
断言(assertion)= 「检查上下文,但不消费字符」。它本身不进入匹配结果,只用来约束「这个位置周围必须长什么样」。
| 写法 | 名称 | 含义 |
|---|---|---|
(?=...) | 先行断言 | 右边必须满足 ... |
(?!...) | 否定先行断言 | 右边必须不满足 ... |
(?<=...) | 后行断言 | 左边必须满足 ... |
(?<!...) | 否定后行断言 | 左边必须不满足 ... |
常见场景:
- 「找出价格但不要单位」
\d+(?=元\|¥\|RMB) - 「找出后面是冒号的单词」
\w+(?=:) - 「找出前面不是
$的数字」(?<!\$)\d+
8. 两个常用开关
不同工具的「正则设置」面板里,最常见的就这两个开关——其他的几乎用不到:
| 开关 | 关闭时(默认) | 打开时 |
|---|---|---|
| 区分大小写 | Hello 不匹配 hello | Hello 也可以匹配 hello、HELLO |
| 全局匹配 | 只处理第一个匹配 | 处理所有匹配(替换时尤其重要) |
替换功能几乎总是要打开「全局匹配」,否则只换一处。
9. 速查表
9.1 元字符
| 符号 | 含义 |
|---|---|
. | 任意单字符(默认不含换行) |
^ | 开头 |
$ | 结尾 |
| | 或 |
\ | 转义下一个字符 |
( ) | 分组 + 捕获 |
[ ] | 字符类 |
{ } | 量词次数 |
9.2 字符类
| 写法 | 含义 |
|---|---|
[abc] | a 或 b 或 c |
[^abc] | 不是 a/b/c |
[a-z] | a 到 z 任一字符 |
\d | 数字 = [0-9] |
\D | 非数字 |
\w | 单词字符 = [A-Za-z0-9_] |
\W | 非单词字符 |
\s | 空白 |
\S | 非空白 |
\n \t \r | 换行/制表/回车 |
9.3 量词
| 写法 | 含义 |
|---|---|
? | 0 或 1 |
* | 0 或更多 |
+ | 1 或更多 |
{n} | 恰好 n |
{n,} | 至少 n |
{n,m} | n 到 m |
量词? | 切换为懒惰 |
9.4 锚点与边界
| 写法 | 含义 |
|---|---|
^ | 字符串开头 |
$ | 字符串结尾 |
\b | 单词边界 |
\B | 非单词边界 |
9.5 分组与引用
| 写法 | 含义 |
|---|---|
(...) | 捕获组 |
(?:...) | 非捕获组 |
(?<name>...) | 命名捕获组 |
\1 \2 … | 反向引用(在正则内) |
\k<name> | 命名反向引用 |
9.6 断言
| 写法 | 含义 |
|---|---|
(?=...) | 右边必须是 ... |
(?!...) | 右边必须不是 ... |
(?<=...) | 左边必须是 ... |
(?<!...) | 左边必须不是 ... |
9.7 替换字符串语法
| 写法 | 含义 |
|---|---|
$0 | 整体匹配 |
$1…$9 | 第 N 个捕获组 |
${name} | 命名捕获组 |
$$ | 字面 $ |
| 其他文本 | 照原样写入 |
10. 实战案例集
隐藏手机号中间四位
给数字加千位分隔
含义:在某个数字右边,正好有若干组 3 位数字,并且再往右不是数字——这样的位置就插一个逗号。
更多速用配方
| 目的 | 搜索 | 替换为 |
|---|---|---|
| 提取所有 URL | https?://\S+ | — |
| 校验邮箱(够用版) | ^[\w.+-]+@[\w-]+(\.[\w-]+)+$ | — |
| 提取中文文本 | [一-鿿]+ | — |
| 合并多个空行 | \n{3,} | \n\n |
2026/05/17 → 2026-05-17 | (\d{4})/(\d{2})/(\d{2}) | $1-$2-$3 |
| 提取 Markdown 标题文字 | ^#+\s*(.+?)\s*$ | $1 |
| 删除所有 HTML 标签 | <[^>]+> | (空) |
**粗体** 改 __粗体__ | \*\*([^*]+)\*\* | __$1__ |
到这里你已经掌握了正则的全部核心能力——剩下的就是练习。 建议挑一个上面的案例,自己改输入文本,观察匹配/替换结果,几次之后就会形成肌肉记忆。
11. 更多资源
本教程及配图由AI编写,如果你想要学习其它教程,推荐前往 菜鸟教程 或直接搜索 正则表达式 教程 阅读更多进阶教程