正则表达式全解析:从基础到实战(附 Python re 模块用法)
正则表达式(Regular Expression),常简写为regex、regexp或re,是一种独立于编程语言但被主流语言广泛兼容的字符串处理工具。它通过特定模式对字符串进行检索、提取、替换等操作,是处理文本的高效利器。本文将从基础规则到实战应用,全面解析正则表达式的用法。
一、正则表达式基础
1. 本质与工具
正则表达式本质是由特殊字符组成的模式匹配串(Pattern),在 Python 中通过Pattern类表示。
推荐辅助学习工具:RegexBuddy4.exe,可直观测试正则匹配效果。
2. 基础匹配规则
基础规则用于匹配单个字符,核心如下:
| 规则 | 说明 | 示例 |
|---|---|---|
xyz | 匹配字面量xyz(非特殊字符) | abc匹配 "abc" |
[xyz] | 匹配 x、y、z 中的任意一个 | [abc]匹配 "a"、"b" 或 "c" |
[a-z] | 匹配区间内字符(-表示区间,包含两端) | [0-9]匹配任意数字 |
[^xyz] | 匹配除 x、y、z 外的任意字符(^在中括号首位表示 “非”) | [^0-9]匹配非数字 |
\d | 等价于[0-9](任意数字) | |
\D | 等价于[^0-9](非数字) | |
\w | 匹配字母、数字、下划线(Python 中含中文) | 等价于[a-zA-Z0-9_] |
\W | 匹配非\w字符 | |
\s | 匹配空白符(空格、\t制表符、\n换行符) | |
\S | 匹配非空白符 | |
\b | 单词边界(需配合其他规则使用) | \bcat\b匹配独立的 "cat" |
. | 匹配除换行符外的任意字符 | |
\. | 转义匹配小数点(特殊字符需用\转义) |
示例:
[0-2457-9]:匹配除 3、6 外的数字(区间与字面量结合)[a-zA-Z0-9]:匹配任意字母或数字
二、多字符与贪婪 / 非贪婪匹配
1. 多字符匹配规则
通过限定符指定字符重复次数(X代表基础规则):
| 规则 | 说明 | 示例 |
|---|---|---|
X{n} | 匹配 n 个 X | \d{3}匹配 3 个连续数字 |
X{n,} | 至少匹配 n 个 X(尽可能多) | \d{2,}匹配 2 个及以上数字 |
X{n,m} | 匹配 n 到 m 个 X(m≥n) | \d{1,3}匹配 1-3 个数字 |
实战案例:
- 手机号匹配:
1[3-9]\d{9}(1 开头,第 2 位 3-9,后 9 位数字)
2. 贪婪式匹配
默认匹配尽可能多的字符:
| 规则 | 说明 | 等价形式 |
|---|---|---|
X* | 至少 0 个 X | X{0,} |
X+ | 至少 1 个 X | X{1,} |
X? | 最多 1 个 X(0 或 1 个) | X{0,1} |
示例:邮箱匹配(简化版)
[a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+){1,2}
- 账号:至少 1 个字母 / 数字 / 下划线
- 域名:
xx.xx或xx.xx.xx格式
3. 非贪婪式匹配
在贪婪规则后加?,匹配尽可能少的字符(不建议用于正则尾部):
| 规则 | 说明 |
|---|---|
X*? | 至少 0 个 X(非贪婪) |
X+? | 至少 1 个 X(非贪婪) |
X?? | 最多 1 个 X(非贪婪) |
示例:
3\d+?:匹配 "3" 后接最少 1 个数字(如 "31")\d+?3:匹配 "3" 前接最少 1 个数字(如 "13")
三、分组与选择
1. 分组((...))
将部分规则视为整体,方便提取匹配结果:
- 普通分组:
(...),可通过编号引用 - 非捕获分组:
(?:...),仅作为整体匹配,不参与结果提取 - 命名捕获分组:
(?P<name>...)(Python)或(?<name>...)(Java/JS),通过名称提取
示例:
邮箱命名分组:(?P<account>[a-zA-Z0-9_]+)@[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+){1,2}
可通过account直接获取账号部分。
2. 分组引用(\n)
通过\n引用第 n 个分组的匹配内容:
- 示例:
(\d{2})-(\d{2})-\1,匹配 "12-34-12"(年份重复)
3. 选择(|)
匹配多个规则中的一个,类似 “或” 逻辑:
示例:身份证年份与日期匹配
[0-9]\d{5}(?P<year>(?:19|20)\d{2})(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]
- 年份:1900-2099
- 月份:01-12
- 日期:01-31
四、限定符与断言
1. 限定符(边界匹配)
^:匹配字符串开头(如^abc匹配以 "abc" 开头的字符串)$:匹配字符串结尾(如abc$匹配以 "abc" 结尾的字符串)- 中文匹配:
[\u4e00-\u9fa5](匹配任意中文字符)
2. 断言(条件匹配)
根据位置前后的条件匹配,不包含在结果中:
| 类型 | 规则 | 说明 |
|---|---|---|
| 正向确定断言 | X(?=Y) | 匹配 X,且 X 后为 Y |
| 正向否定断言 | X(?!Y) | 匹配 X,且 X 后不为 Y |
| 反向确定断言 | (?<=Y)X | 匹配 X,且 X 前为 Y |
| 反向否定断言 | (?<!Y)X | 匹配 X,且 X 前不为 Y |
示例:
\d+?(?=5):匹配后面是 5 的数字(如 "125" 中的 "12")(?<=5)\d+:匹配前面是 5 的数字(如 "512" 中的 "12")
五、Python re 模块实战
Python 的re模块提供正则表达式操作,核心功能如下:
1. 编译正则(compile)
将字符串正则转为Pattern对象,提高复用效率:
python
import re
pattern = re.compile(r'\d+') # 编译匹配数字的正则
2. 检索与提取
findall(pattern, string):返回所有匹配结果的列表finditer(pattern, string):返回匹配结果的迭代器(元素为Match对象)search(pattern, string):返回第一个匹配的Match对象match(pattern, string):仅匹配字符串开头,返回Match对象
Match对象方法:
group(n):获取第 n 个分组的匹配结果(n=0 为整体)groups():返回所有分组的元组groupdict():返回命名分组的字典(键为名称)span(n):返回第 n 个分组的起止索引
3. 匹配校验
fullmatch(pattern, string):完全匹配字符串(等价于^...$)
4. 字符串操作
split(pattern, string):按匹配结果拆分字符串python
re.split(r'\d+', 'ab234g465gsf') # 结果:['ab', 'g', 'gsf']sub(pattern, repl, string):替换匹配内容(repl可为字符串或函数)python
# 隐藏手机号中间4位 re.sub(r'(?<=1[3-9]\d)(\d{4})(?=\d{4})', '****', '13312344321')subn(pattern, repl, string):返回替换结果和替换次数的元组
5. 修饰符
通过flags参数设置匹配模式:
re.I:忽略大小写re.S(DOTALL):.匹配包括换行符在内的所有字符re.M(MULTILINE):多行模式,^和$匹配每行首尾
示例:
python
# 提取每一行以字母开头的数据
string = """
234654dsfsdg
abc34ABD13234
"""
re.findall(r'^[a-zA-Z].+', string, re.M) # 结果:['abc34ABD13234']
六、总结
正则表达式是处理字符串的强大工具,掌握其基础规则、分组逻辑和 Python re 模块的用法,可大幅提升文本处理效率。建议结合RegexBuddy等工具边练边学,从简单匹配逐步过渡到复杂校验(如邮箱、身份证等),实战中加深理解。
希望本文能帮助你快速入门正则表达式,更多进阶技巧可结合具体场景深入探索!
