11 正则表达式¶
一、前言:正则表达式到底是啥?¶
正则表达式(Regular Expression, Regex) 是一种“字符串模式匹配语言”。它能用简洁规则描述你要找的文本模式,比如:
- 找手机号、邮箱、身份证
- 找到日志里的时间、IP、URL
- 批量替换文本(把多个空格变成一个;把
YYYY/MM/DD变成YYYY-MM-DD) - 校验输入合法性(密码强度、用户名格式)
可以用一句话来总结:正则 = 用规则描述字符串结构,并进行查找/匹配/提取/替换,简要说:
- 匹配(match/test):判断是否符合规则
- 提取(find/capture):从字符串中“抓”想要的部分
- 替换(replace/sub):把匹配到的内容替换成别的
二、正则字符对照表¶
这里我们先给出重要的参数对照表,因为这些是理解正则表达式的基础,你可以先不完全理解,后面会展开讲。
2.1 元字符速查表¶
| 分类 | 符号 | 含义 | 例子 | 说明 |
|---|---|---|---|---|
| 通配 | . |
匹配除换行外任意字符 | a.c |
abc、a1c |
| 行首行尾 | ^ |
行/字符串开始 | ^abc |
以 abc 开头 |
| 行首行尾 | $ |
行/字符串结束 | abc$ |
以 abc 结尾 |
| 选择 | \| |
或 | cat\|dog |
匹配 cat 或 dog |
| 分组 | (...) |
捕获分组 | (ab)+ |
捕获匹配内容 |
| 非捕获分组 | (?:...) |
不捕获,只分组 | (?:ab)+ |
更省资源 |
| 字符集 | [...] |
匹配其中任意一个字符 | [abc] |
a 或 b 或 c |
| 取反字符集 | [^...] |
匹配不在集合里的字符 | [^0-9] |
非数字 |
| 转义 | \ |
转义元字符/表示特殊类 | \. \d |
匹配点/数字 |
| 边界 | \b |
单词边界 | \bcat\b |
只匹配独立 cat |
| 非边界 | \B |
非单词边界 | \Bcat\B |
cat 两侧都不是边界 |
| 反向引用 | \1 \2 ... |
引用第 n 个捕获组 | (\w+)\s+\1 |
重复单词 |
| 前瞻 | (?=...) |
右侧必须能匹配(不消耗字符) | a(?=b) |
a 后面必须是 b |
| 负前瞻 | (?!...) |
右侧必须不能匹配 | a(?!b) |
a 后面不能是 b |
| 后顾 | (?<=...) |
左侧必须能匹配(不消耗字符) | (?<=\$)\d+ |
找 $ 后数字 |
| 负后顾 | (?<!...) |
左侧必须不能匹配 | (?<!\$)\d+ |
前面不是 $ 的数字 |
2.2 特殊字符类速查表¶
| 符号 | 含义 | 等价 | 例子 |
|---|---|---|---|
\d |
数字 | [0-9] |
\d+ |
\D |
非数字 | [^0-9] |
\D+ |
\w |
单词字符 | [A-Za-z0-9_] |
\w+ |
\W |
非单词字符 | [^A-Za-z0-9_] |
\W+ |
\s |
空白字符 | [ \t\r\n\f\v] |
\s+ |
\S |
非空白字符 | [^ \t\r\n\f\v] |
\S+ |
[一-龢] |
中文汉字 | [\u4e00-\u9fa5](unicode编码) |
\S+ |
2.3 字符集:写正则的基本功¶
(1)最常见写法
[abc]:匹配 a 或 b 或 c 任意一个字符[a-z]:小写字母[A-Z]:大写字母[0-9]:数字[a-zA-Z0-9_]:等价\w(很多场景更可控)
(2)取反 [^...]
[^0-9]:匹配非数字[^,\n]+:匹配不含逗号/换行的一段(CSV/日志常用)
(3)字符集里的特殊规则
-在中间表示范围:[a-z],若要匹配字面量-,放开头或结尾:[-a]或[a-]或转义\-^在[]开头才是“取反”:[^a],如果不在开头就是普通字符:[a^b]]如果要作为普通字符,通常放在最开头:[]a],或者转义.在[]里是普通点,不是通配:[.]
三、量词对照表¶
量词控制 “前一个元素出现多少次”。前一个元素可以是:一个字符、一个字符类、一个分组、一个点 . 等。
3.1 基本量词表(默认是贪婪匹配)¶
| 量词 | 含义 | 等价说法 | 示例 | 能匹配 |
|---|---|---|---|---|
* |
0 次或多次 | “可有可无很多次” | a* |
""、a、aaaa |
+ |
1 次或多次 | “至少一次” | a+ |
a、aaaa |
? |
0 次或 1 次 | “可有可无一次” | a? |
""、a |
{n} |
恰好 n 次 | 固定次数 | a{3} |
aaa |
{n,} |
至少 n 次 | 下限 | a{2,} |
aa、aaaa |
{n,m} |
n 到 m 次 | 范围 | a{2,4} |
aa、aaa、aaaa |
3.2 懒惰量词表¶
默认是贪婪:尽可能多吃,加 ? 变懒惰:尽可能少吃(但仍要匹配成功)
| 贪婪 | 懒惰 | 示例 | 字符串 | 贪婪匹配 | 懒惰匹配 |
|---|---|---|---|---|---|
* |
*? |
<.*> |
<a><b> |
<a><b> |
<a> |
+ |
+? |
".+?" |
"a" "b" |
"a" "b"(尽量长) |
"a"(尽量短) |
{n,m} |
{n,m}? |
a{2,4}? |
aaaa |
aaaa |
aa |
3.3 修饰符 Flags¶
| Flag | 含义 | 常见名称 | 作用 |
|---|---|---|---|
i |
忽略大小写 | ignoreCase | abc 匹配 ABC |
m |
多行模式 | multiline | ^ $ 作用于每一行 |
s |
点号匹配换行 | dotAll | . 可以匹配 \n |
g |
全局查找 | global | 找到所有匹配(JS 常见) |
u |
Unicode 模式 | unicode | 处理 Unicode 更正确(JS 常见) |
四、正则表达式中小众但好用的表达式¶
在前面的元字符速查表中,大部分都是比较常用的,我们在这一节对一些小众但非常实用的方法进行详细介绍
(1) 捕获分组:例如提取年月日
- 正则:
(\d{4})-(\d{2})-(\d{2}) - 字符串:
2026-01-06 - 捕获组:组1:
2026、组2:01,组3:06
(2)非捕获分组
当你只是想用分组来配合量词/优先级,但不想占用捕获编号时,用它!比如上面这个日期分隔符可能是 - 或 /,对于新手而言,肯定容易写成(\d{4})(-|/)(\d{2})(-|/)(\d{2}),这样有一个问题,就是分隔符根本不是我们关心的数据,却占了编号
所以正确的写法是:(\d{4})(?:-|/)(\d{2})(?:-|/)(\d{2}) 这样分组会更干净,分隔符不占编号却也能起到分组作用
(3) ^ 与 $
^abc:必须以 abc 开头abc$:必须以 abc 结尾^abc$:整行/整个字符串必须完全等于 abc
(4)单词边界 \b
单词边界 = 两侧字符的 “类型发生变化” 的位置,具体来说:\b 匹配的是这样一个位置:
- 左边是
\w,右边是\W - 或左边是
\W,右边是\w
但是需要注意的是:\b 匹配的是位置,不是字符本身
\bcat\b只匹配独立单词 catconcatenate不会匹配到 cat(因为 cat 不在单词边界)
(5) 前瞻 (?=...):例如匹配后面跟着 px 的数字(提取数值)→ \d+(?=px)→ 16px → 匹配 16
(6)负前瞻 (?!...):例如匹配不是 .jpg 结尾的文件名,* ^.+\.(?!jpg$)\w+$
(7) 后顾 (?<=...):例如匹配 $ 后面的数字→ (?<=\$)\d+→ $199 → 匹配 199
(8)负后顾 (?<!...):例如匹配前面不是 # 的数字, (?<!#)\d+,以上四种前瞻后顾的方法,只匹配位置,不消耗字符
同时注意正则也有运算优先级,常见(从高到低):
- 括号
(...) - 量词
* + ? {}(作用于前一个元素) - 连接(挨着写)
- 选择
|
例如根据 连接>选择 | 的优先级规则,我们知道:
ab|cd等价(ab)|(cd)a(b|c)d才是你想要的 “abd 或 acd”
五、常用正则模板库¶
我们需要知道的是,正则没有“万能”,需要根据不同情境撰写规则,以下模板适合多数工程场景,可以收藏。
以下正则为 工程常用版本,默认单行匹配,必要时配合
^ $使用 使用前请根据业务是否允许空值、前后空白进行微调,可以选择删除行首行尾匹配符
(1)数字 / 字符基础类¶
| 表达式 | 用途 | 表达式 | 用途 |
|---|---|---|---|
^\d+$ |
正整数 | ^-?\d+$ |
整数(含负数) |
^\d{n}$ |
固定 n 位数字 | ^\d{m,n}$ |
m 到 n 位数字 |
^\d+(\.\d+)?$ |
数字或小数 | ^\d+(\.\d{1,2})?$ |
金额(最多 2 位小数) |
^\d{6}$ |
邮编 | ^\d{4}$ |
年份 |
^\d{2}$ |
两位数字 | ^\d+$ |
纯数字字符串 |
(2)空白 / 文本处理类¶
| 表达式 | 用途 | 表达式 | 用途 |
|---|---|---|---|
^\s+$ |
全是空白 | ^\s* |
行首空白 |
\s*$ |
行尾空白 | \n |
换行 |
\s+ |
多个空白 | [ \t]+ |
空格或制表符 |
(3)字符 / 单词边界类¶
| 表达式 | 用途 | 表达式 | 用途 |
|---|---|---|---|
\w+ |
单词字符 | \W+ |
非单词字符 |
\bword\b |
独立单词 | \Bword\B |
单词内部 |
\b\d+\b |
独立数字 | (?<!\w)\d+(?!\w) |
精确数字边界 |
[A-Za-z]+ |
英文字母 | [A-Za-z0-9_]+ |
标识符 |
(4)账号 / 身份 / 校验类¶
| 表达式 | 用途 | 表达式 | 用途 |
|---|---|---|---|
^[A-Za-z]\w{5,19}$ |
用户名 | ^\w{6,20}$ |
简单账号 |
^(?=.*[A-Za-z])(?=.*\d).{8,}$ |
字母+数字密码 | ^(?=.*\d)(?=.*[A-Z]).{8,}$ |
强密码 |
^1[3-9]\d{9}$ |
中国手机号 | ^\+86\s?1[3-9]\d{9}$ |
含区号手机号 |
(5)日期 / 时间类¶
| 表达式 | 用途 | 表达式 | 用途 |
|---|---|---|---|
^\d{4}-\d{2}-\d{2}$ |
日期(-分隔) | ^\d{4}/\d{2}/\d{2}$ |
日期(/分隔) |
^\d{2}:\d{2}:\d{2}$ |
时间 | ^\d{2}:\d{2}$ |
分钟级 |
(6)提取 / 替换 / 日志分析类¶
| 表达式 | 用途 | 表达式 | 用途 |
|---|---|---|---|
".*?" |
双引号内容 | '.*?' |
单引号内容 |
<[^>]+> |
HTML 标签 | <(\w+)[^>]*>.*?</\1> |
成对标签 |
\d+(?=px) |
提取 px 数值 | (?<=\$)\d+ |
金额数字 |
\bERROR\b |
错误日志 | \bWARN\b |
警告日志 |
本期给大家系统总结了正则表达式的主要用法,但是还是得说一句,正则不是靠记忆,而是靠“查表 + 理解结构”,以上这些表,就是你写正则时最值得翻的那一页,你可以根据需要收藏。