Python 正则表达式 (re 模块) 实战指南
Python 正则表达式 (re 模块) 实战指南
通过分步示例掌握 Python re 模块正则表达式威力,涵盖常见模式、匹配技巧与进阶函数。
什么是正则表达式?
正则表达式 是定义搜索模式的字符序列。例如模式 ^a...s$ 匹配任意以 a 开头、以 s 结尾的五字母字符串。
^a...s$
模式可用于匹配字符串。下表演示该模式对不同输入的行为:
| 表达式 | 字符串 | 匹配? |
|---|---|---|
^a...s$ | abs | 不匹配 |
alias | 匹配 | |
abyss | 匹配 | |
Alias | 不匹配 | |
An abacus | 不匹配 |
Python re 模块提供处理 RegEx 所需工具。快速示例用 re.match() 检查模式:
import re
pattern = '^a...s$'
test_string = 'abyss'
result = re.match(pattern, test_string)
if result:
print("Search successful.")
else:
print("Search unsuccessful.")
模式找到时 re.match() 返回匹配对象;否则返回 None。
用元字符指定模式
元字符是正则引擎特殊解释的符号。最常用元字符速查:
[] . ^ $ * + ? {} () \ |
方括号:[]
方括号定义要匹配的字符集。如 [abc] 匹配 a、b 或 c 的单次出现。
| 表达式 | 字符串 | 匹配? |
|---|---|---|
[abc] | a | 1 匹配 |
ac | 2 匹配 | |
Hey Jude | 不匹配 | |
abc de ca | 5 匹配 |
用连字符表示范围,如 [a-e] 等于 [abcde]。反转集合在左括号后加 ^,如 [^abc] 匹配除 a、b、c 外任意字符。
句点:.
句点匹配除换行符外任意单字符。
| 表达式 | 字符串 | 匹配? |
|---|---|---|
.. | a | 不匹配 |
ac | 1 匹配 | |
acd | 1 匹配 | |
acde | 2 匹配(含 4 字符) |
插入符:^ 与美元符:$
插入符断言字符串开始;美元符断言结束。如 ^a 匹配以 a 开头的字符串,a$ 匹配以 a 结尾的字符串。
| 表达式 | 字符串 | 匹配? |
|---|---|---|
^a | a | 1 匹配 |
abc | 1 匹配 | |
bac | 不匹配 | |
^ab | abc | 1 匹配 |
acb | 不匹配(以 a 开头但非 b 后跟) |
| 表达式 | 字符串 | 匹配? |
|---|---|---|
a$ | a | 1 匹配 |
formula | 1 匹配 | |
cab | 不匹配 |
量词:*、+、?、{n,m}
这些符号控制前一个元素出现次数。
*—— 零次或多次。+—— 一次或多次。?—— 零次或一次。{n,m}—— 至少 n 至多 m 次。
示例:
| 表达式 | 字符串 | 匹配? |
|---|---|---|
ma*n | mn | 1 匹配 |
man | 1 匹配 | |
maaan | 1 匹配 | |
main | 不匹配(a 非 n 后跟) | |
woman | 1 匹配 |
| 表达式 | 字符串 | 匹配? |
|---|---|---|
ma+n | mn | 不匹配(无 a) |
man | 1 匹配 | |
maaan | 1 匹配 | |
main | 不匹配(a 非 n 后跟) | |
woman | 1 匹配 |
| 表达式 | 字符串 | 匹配? |
|---|---|---|
ma?n | mn | 1 匹配 |
man | 1 匹配 | |
maaan | 不匹配(多于一个 a) | |
main | 不匹配(a 非 n 后跟) | |
woman | 1 匹配 |
| 表达式 | 字符串 | 匹配? |
|---|---|---|
a{2,3} | abc dat | 不匹配 |
abc daat | 1 匹配(在 daat) | |
aabc daaat | 2 匹配(在 aabc 和 daaat) | |
aabc daaaat | 2 匹配(在 aabc 和 daaaat) |
常用模式:[0-9]{2,4} 匹配 2 到 4 连续数字。
| 表达式 | 字符串 | 匹配? |
|---|---|---|
[0-9]{2,4} | ab123csde | 1 匹配(在 ab123csde) |
12 and 345673 | 3 匹配(12、3456、73) | |
1 and 2 | 不匹配 |
选择:|
竖线实现逻辑或。如 a|b 匹配含 a 或 b 的字符串。
| 表达式 | 字符串 | 匹配? |
|---|---|---|
a|b | cde | 不匹配 |
ade | 1 匹配(在 ade) | |
acdbea | 3 匹配(在 acdbea) |
分组:()
括号分组子模式并捕获匹配子串。例:(a|b|c)xz 匹配含 a、b 或 c 后跟 xz 的字符串。
| 表达式 | 字符串 | 匹配? |
|---|---|---|
(a|b|c)xz | ab xz | 不匹配 |
abxz | 1 匹配(在 abxz) | |
axz cabxz | 2 匹配(在 axzbc cabxz) |
转义:\
用反斜杠将元字符视为字面量。如 \$a 匹配字面序列 $a 而非将 $ 视为字符串结束锚点。
特殊序列
特殊序列简化常用模式。下为参考列表及示例。
字符串开始:\A
| 表达式 | 字符串 | 匹配? |
|---|---|---|
\Athe | the sun | 匹配 |
In the sun | 不匹配 |
单词边界:\b
| 表达式 | 字符串 | 匹配? |
|---|---|---|
\bfoo | football | 匹配 |
a football | 匹配 | |
afootball | 不匹配 | |
foo\b | the foo | 匹配 |
the afoo test | 匹配 | |
the afootest | 不匹配 |
非单词边界:\B
| 表达式 | 字符串 | 匹配? |
|---|---|---|
\Bfoo | football | 不匹配 |
a football | 不匹配 | |
afootball | 匹配 | |
foo\B | the foo | 不匹配 |
the afoo test | 不匹配 | |
the afootest | 匹配 |
数字:\d / 非数字:\D
| 表达式 | 字符串 | 匹配? |
|---|---|---|
\d | 12abc3 | 3 匹配(在 12abc3) |
Python | 不匹配 | |
\D | 1ab34"50 | 3 匹配(在 1ab34"50) |
1345 | 不匹配 |
空白:\s / 非空白:\S
| 表达式 | 字符串 | 匹配? |
|---|---|---|
\s | Python RegEx | 1 匹配 |
PythonRegEx | 不匹配 | |
\S | a b | 2 匹配(在 a b) |
| 不匹配 |
单词字符:\w / 非单词:\W
| 表达式 | 字符串 | 匹配? |
|---|---|---|
\w | 12&": ;c | 3 匹配(在 12": ;c) |
"%> ! | 不匹配 | |
\W | 1a2%c | 1 匹配(在 1a2%c) |
Python | 不匹配 |
字符串结束:\Z
| 表达式 | 字符串 | 匹配? |
|---|---|---|
Python\Z | I like Python | 1 匹配 |
I like Python Programming | 不匹配 | |
Python is fun. | 不匹配 |
提示:用在线正则测试器如 regex101 快速构建调试模式。
在 Python 中使用 RegEx
Python re 模块提供丰富函数和常量进行正则操作。导入:
import re
以下是最常用工具及用法。
re.findall()
返回字符串中所有非重叠匹配列表。
# 从字符串提取所有数字
import re
string = 'hello 12 hi 89. Howdy 34'
pattern = '\d+'
result = re.findall(pattern, string)
print(result) # 输出: ['12', '89', '34']
无匹配时返回空列表。
re.split()
在模式匹配处分割字符串,返回子串列表。
import re
string = 'Twelve:12 Eighty nine:89.'
pattern = '\d+'
result = re.split(pattern, string)
print(result) # 输出: ['Twelve:', ' Eighty nine:', '.']
可选 maxsplit 限制分割次数。0(默认)在每处匹配分割。
import re
string = 'Twelve:12 Eighty nine:89 Nine:9.'
pattern = '\d+'
# 仅在首次出现分割
result = re.split(pattern, string, 1)
print(result) # 输出: ['Twelve:', ' Eighty nine:89 Nine:9.']
re.sub()
用替换字符串替换所有模式匹配。
# 移除所有空白字符
import re
string = 'abc 12\nde 23 \n f45 6'
pattern = '\s+'
replace = ''
new_string = re.sub(pattern, replace, string)
print(new_string) # 输出: abc12de23f456
限制替换次数提供 count 参数。0 替换所有匹配。
new_string = re.sub(r'\s+', replace, string, 1)
print(new_string) # 输出:
# abc12de 23
# f45 6
re.subn()
类似 re.sub(),但返回包含新字符串和替换次数的元组。
new_string = re.subn(pattern, replace, string)
print(new_string) # 输出: ('abc12de23f456', 4)
re.search()
找到模式首次匹配位置。
string = "Python is fun"
match = re.search('\\APython', string)
if match:
print("pattern found inside the string")
else:
print("pattern not found")
# 输出: pattern found inside the string
匹配对象
匹配时 re.search() 返回 Match 对象。常用方法和属性:
group()—— 匹配子串。start()/end()—— 匹配索引。span()—— (start, end) 元组。groups()—— 所有捕获组。
string = '39801 356, 2102 1111'
pattern = '(\d{3}) (\d{2})'
match = re.search(pattern, string)
if match:
print(match.group())
print(match.group(1))
print(match.group(2))
print(match.groups())
print(match.start(), match.end(), match.span())
else:
print("pattern not found")
# 输出:
# 801 35
# 801
# 35
# ('801', '35')
# 2 8 (2, 8)
使用原始字符串(前缀 r)
字符串字面量前加 r 将反斜杠视为字面字符,防止意外转义序列。这在正则模式中特别有用。
string = '\n and \r are escape sequences.'
result = re.findall(r'[\n\r]', string)
print(result) # 输出: ['\n', '\r']
深入探索 re 模块请参考官方 Python 文档。
Python
- Python关键字与标识符:掌握保留字与命名规范
- 精通Python数据类型:实战指南
- 精通Python运算符:全面指南
- 精通Python Pass语句:实战指南
- 精通Python函数参数:位置、关键字与默认参数
- 精通 Python 字典:创建、操作与进阶技巧
- 精通 Python 迭代器:工作原理与自定义构建
- Python 闭包详解:嵌套函数如何捕获变量
- 精通 Python datetime:日期、时间与时区实战指南
- 精通 Python time 模块:函数、结构体与实战示例
- 精通 Python time.sleep():最佳实践、多线程与实战案例
- Python 语言概览:高级、可读、交互式与面向对象