Python轮子:re~文本匹配重武器

原文链接:http://www.juzicode.com/python-module-re

Python的re模块提供正则表达式操作功能,用于高效处理字符串匹配、替换、分割等操作,适合处理复杂文本模式匹配需求。

应用场景

  • 表单数据验证(邮箱/手机号/身份证)
  • 日志文件关键信息提取
  • 文本内容批量替换
  • 网络爬虫数据清洗
  • 配置文件解析
  • 自然语言处理预处理

模块导入

import re

使用方法

1)基础匹配(match)

从字符串起始位置匹配模式,成功返回匹配对象,否则返回None。

# juzicode.com/VX公众号:juzicode
import re

pattern = r'^1[3-9]\d{10}$'
phone = '13800138000'
result = re.match(pattern, phone)
print('验证结果1:', '有效' if result else '无效')

pattern = r'^1[3-9]\d{9}$'
phone = '13800138000'
result = re.match(pattern, phone)

print('验证结果2:', '有效' if result else '无效')

运行结果:

验证结果1: 有效
验证结果2: 无效

2)全文搜索(search)

扫描整个字符串查找第一个匹配项,适用于日志分析等场景。

# juzicode.com/VX公众号:juzicode
import re

# 提取日期信息
text = '报告生成时间:2025-03-25 15:30'
date_pattern = r'\d{4}-\d{2}-\d{2}'
match = re.search(date_pattern, text)
print('找到日期1:',match.group() if match else match)

text = '报告生成时间:20250325 15:30'
date_pattern = r'\d{4}-\d{2}-\d{2}'
match = re.search(date_pattern, text)
print('找到日期2:',match.group() if match else match)

运行结果:

找到日期1: 2023-07-25
找到日期2: None

3)批量查找(findall)

返回所有非重叠匹配的字符串列表,适用于数据采集场景。

# juzicode.com/VX公众号:juzicode
import re

# 获取所有金额
content = '订单金额:¥198,运费:¥15,总计:¥213'
amount_pattern = r'¥(\d+)'
amounts = re.findall(amount_pattern, content)
print('金额列表:', amounts)

运行结果:

金额列表: ['198', '15', '213']

4)文本替换(sub)

替换字符串中的匹配项,支持回调函数,适用于数据脱敏。

# juzicode.com/VX公众号:juzicode
import re

# 手机号脱敏处理
text = '联系方式:13812345678'
masked = re.sub(r'(\d{3})\d{4}(\d{4})', r'\1****\2', text)
print('脱敏结果:', masked)

运行结果:

脱敏结果: 联系方式:138****5678

5)智能分割(split)

根据模式分割字符串,比普通split更灵活。

# juzicode.com/VX公众号:juzicode
import re

# 多分隔符分割
text = '苹果,香蕉;西瓜|菠萝'
items = re.split(r'[,;|;]', text)
print('分割结果:', items)

运行结果:

分割结果: ['苹果', '香蕉', '西瓜', '菠萝']

6)分组捕获

使用()捕获子模式,提取结构化数据。

# juzicode.com/VX公众号:juzicode
import re

# 解析日志条目
log = '[ERROR] 2025-05-25 15:00:00 服务器连接超时 (code:500)'
pattern = r'\[(\w+)\] (\d{4}-\d{2}-\d{2}) .+?\(code:(\d+)\)'
match = re.search(pattern, log)
print(f'级别: {match.group(1)}, 时间: {match.group(2)}, 状态码: {match.group(3)}')

运行结果:

级别: ERROR, 时间: 2025-05-25, 状态码: 500

7)预编译模式

提升重复使用时的性能,支持flags参数。

# juzicode.com/VX公众号:juzicode
import re

# 忽略大小写匹配
compiled = re.compile(r'hello', flags=re.IGNORECASE)
texts = ['Hello World', 'HELLO Python', 'hi there']
matches = [t for t in texts if compiled.search(t)]
print('匹配结果:', matches)

运行结果:

匹配结果: ['Hello World', 'HELLO Python']

8)非贪婪匹配

使用.*?实现最小匹配,避免过度匹配问题,适用于提取HTML标签内容等场景。.*?实现最短匹配,避免捕获到后续标签内容,适用于嵌套结构解析。

# juzicode.com/VX公众号:juzicode
import re

# 提取首个div内容 
html = '<div>欢迎关注桔子code</div><div class="content">正文内容</div>' 
match = re.search(r'<div.*?>(.*?)</div>', html) 
print('提取结果:', match.group(1))

运行结果:

提取结果: 欢迎关注桔子code

9)前后查找断言

使用(?=...)(?<=...)实现无捕获匹配,适合密码规则验证等场景。(?=.*[A-Z]) 表示必须包含大写字母,(?=.*\d) 表示必须包含数字,.{8,} 要求至少8位长度

# juzicode.com/VX公众号:juzicode
import re
# 验证包含大写字母和数字的密码 
password = "Secret123" 
pattern = r'^(?=.*[A-Z])(?=.*\d).{8,}$' 
print('密码有效' if re.match(pattern, password) else '密码无效')

运行结果:

密码有效

10)动态替换函数

使用函数作为替换参数实现智能替换,适用于需要动态处理的替换场景。

# juzicode.com/VX公众号:juzicode
import re
# 将价格数值翻倍 
text = "苹果 5元, 香蕉 3元, 橙子 4元" 
def double_price(match): 
  return str(int(match.group(1)) * 2) 

result = re.sub(r'(\d+)元', lambda m: f"{double_price(m)}元", text) 
print("新价格:", result)

运行结果:

新价格: 苹果 10元, 香蕉 6元, 橙子 8元

总结

re模块是处理复杂文本的利器:

  • 提供完整的正则表达式功能支持
  • 支持分组捕获、命名分组等高级特性
  • 具备模式预编译优化机制
  • 跨平台兼容性好

注意事项:

  • 复杂正则表达式需添加注释
  • 注意贪婪模式与懒惰模式的区别
  • 处理大量数据时考虑性能优化
  • HTML/XML解析建议使用专用解析库

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注