适用场景:Python、Shell(grep/sed/awk)、JavaScript、Java 等
核心理念:正则的"思想"通用,语法"近似但不完全通用"
目录
- 一、什么是正则表达式
- 二、正则表达式的"通用性"
- 三、最基础元字符
- 四、字符类
- 五、量词(重复)
- 六、分组与捕获
- 七、锚点与边界
- 八、转义字符
- 九、贪婪与非贪婪
- 十、高级特性(非通用,慎用)
- [十一、Python 实战示例](#十一、Python 实战示例)
- [十二、Shell 实战示例](#十二、Shell 实战示例)
- [十三、常见正则对照表(Python vs Shell)](#十三、常见正则对照表(Python vs Shell))
- 十四、跨语言"安全子集"
- 十五、调试与练习工具
- 十六、最佳实践与常见坑
- [十七、速查表(Cheat Sheet)](#十七、速查表(Cheat Sheet))
- 十八、学习路线建议
一、什么是正则表达式
正则表达式(Regular Expression,简称 Regex / RegExp )是一种用来描述字符串模式的"微型语言"。
它可以用来完成这些任务:
- 判断字符串是否符合某种格式(校验)
- 从文本中提取想要的内容(提取)
- 批量替换文本(替换)
- 按规则切分字符串(分割)
通俗理解 :
正则表达式就像是一个"字符串模具",只要字符串能套进去,就说明它符合规则。
举个例子
匹配一个手机号(11 位数字):
regex
^\d{11}$
二、正则表达式的"通用性"
✅ 思想通用
以下概念在所有语言/工具中含义基本一致:
- 用
.表示任意字符 - 用
*表示"前面的东西重复 0 次或多次" - 用
^、$表示开头、结尾 - 用
[a-z]表示字符范围 - 用
()表示分组
❌ 语法和能力不完全通用
不同工具使用不同的正则引擎,主要分为:
| 流派 | 代表工具 |
|---|---|
| POSIX BRE | grep(默认) |
| POSIX ERE | grep -E、sed -E、awk |
| PCRE | Python、PHP、Nginx |
| 语言自有实现 | Java、JavaScript、Go |
📌 结论:
基础语法基本通用,高级特性(如前后查找、非贪婪)不能假设通用。
三、最基础元字符
| 元字符 | 含义 | 示例 | 匹配 |
|---|---|---|---|
. |
任意单个字符(通常不含换行) | a.c |
abc、a-c |
^ |
字符串开头 | ^abc |
abc... |
$ |
字符串结尾 | abc$ |
...abc |
* |
0 次或多次 | ab*c |
ac、abc、abbc |
+ |
1 次或多次 | ab+c |
abc、abbc |
? |
0 次或 1 次 | colou?r |
color、colour |
\ |
转义字符 | \. |
. 本身 |
| ` | ` | 或(多选一) | `cat |
四、字符类
1️⃣ 自定义字符类 [...]
regex
[abc] # a、b 或 c
[a-z] # 小写字母
[A-Z0-9] # 大写字母或数字
2️⃣ 取反 [^...]
regex
[^0-9] # 非数字
[^aeiou] # 非元音字母
3️⃣ 常用"快捷字符类"(注意通用性)
| 写法 | 含义 | 通用性 |
|---|---|---|
\d |
数字 | ✅ Python / ❌ 默认 grep |
\w |
字母数字下划线 | 部分支持 |
\s |
空白字符 | 部分支持 |
\D |
非数字 | 部分支持 |
✅ 跨 Shell 安全写法:
regex
[0-9]
[a-zA-Z]
[ \t\n]
五、量词(重复)
| 量词 | 含义 |
|---|---|
* |
0 次或多次 |
+ |
1 次或多次 |
? |
0 次或 1 次 |
{n} |
恰好 n 次 |
{n,} |
至少 n 次 |
{n,m} |
n 到 m 次 |
示例
regex
\d{4} # 4 位数字
[a-z]{2,5} # 2~5 个小写字母
六、分组与捕获
1️⃣ 基本分组 (...)
regex
(ab)+ # ab 整体重复
2️⃣ 捕获组
regex
(\d{4})-(\d{2})
匹配结果:
| 组号 | 内容 |
|---|---|
| 0 | 整体 |
| 1 | 年 |
| 2 | 月 |
3️⃣ 非捕获组(Python 支持,Shell 较弱)
regex
(?:abc)
七、锚点与边界
| 写法 | 含义 |
|---|---|
^ |
开头 |
$ |
结尾 |
\b |
单词边界(PCRE) |
\B |
非单词边界 |
regex
^abc$ # 整行只能是 abc
\bis\b # 完整单词 is
八、转义字符
以下字符在正则中有特殊含义,必须转义:
. ^ $ * + ? ( ) [ ] { } | \
转义方式:
regex
\.
\*
\$
⚠️ 注意:
- Shell 中还要防止 Shell 自身先解析
- Python 推荐使用原始字符串
r"..."
九、贪婪与非贪婪
贪婪(默认)
regex
<.*>
尽可能多地匹配。
非贪婪(Python 支持)
regex
<.*?>
尽可能少地匹配。
⚠️ sed 等 Shell 工具通常不支持非贪婪。
十、高级特性(非通用,慎用)
| 特性 | 说明 | Python | Shell |
|---|---|---|---|
前瞻 (?=...) |
后面必须是 | ✅ | ❌ |
后顾 (?<=...) |
前面必须是 | ✅ | ❌ |
| 命名分组 | (?P<name>...) |
✅ | ❌ |
| 非贪婪 | *? |
✅ | ❌ |
✅ 跨环境时避免使用这些特性
十一、Python 实战示例
python
import re
text = "我的电话是 13812345678,另一个是 13987654321"
pattern = r"1[3-9]\d{9}"
phones = re.findall(pattern, text)
print(phones)
输出:
['13812345678', '13987654321']
十二、Shell 实战示例
使用 grep -E
sh
grep -E '1[3-9][0-9]{9}' file.txt
使用 sed 替换
sh
sed -E 's/([0-9]{3})-[0-9]{4}/\1-****/'
十三、常见正则对照表(Python vs Shell)
| 功能 | Python | Shell |
|---|---|---|
| 数字 | \d |
[0-9] |
| 非贪婪 | *? |
❌ |
| 分组 | (...) |
(...)(需 -E) |
| 或 | ` | 或 \ |
| 量词 | {n,m} |
{n,m}(需 -E) |
十四、跨语言"安全子集"
✅ 可以放心跨 Python / Shell 使用
regex
^abc
[a-z]+
.*
^start|end$
[0-9]{2,5}
❌ 不建议跨环境使用
\d*?- lookahead / lookbehind
- 命名分组
十五、调试与练习工具
- 在线调试(推荐)
- regex101.com(支持 Python / JS / PCRE)
- Linux 本地
grep -P可开启 PCRE
十六、最佳实践与常见坑
✅ 用原始字符串(Python)
python
r"\d+" # ✅
"\\d+" # ❌
✅ Shell 中优先使用 -E
✅ 先写简单正则,再逐步增强
❌ 不要用正则解析复杂结构(如嵌套 HTML)
十七、速查表(Cheat Sheet)
text
. 任意字符
\d 数字
\w 字母数字下划线
\s 空白
* 0次或多次
+ 1次或多次
? 0次或1次
{n,m} 重复次数
^ 开头
$ 结尾
() 分组
[] 字符类
| 或
十八、学习路线建议
- 先掌握元字符、字符类、量词
- 在 Python 中练习提取与替换
- 在 Shell 中用
grep -E对比差异 - 使用 regex101 调试
- 最后学习高级特性(前瞻后顾)
总结
正则是思想通用、语法近似、实现不同。
掌握"通用子集",理解不同环境的差异,才能真正跨语言使用正则。
📌 建议收藏本表,作为日常开发与运维的速查手册。