【Python】正则表达式的艺术

Python 正则表达式(Regular Expression)的艺术

正则表达式是处理字符串的“瑞士军刀”,但它也是 Python 中最容易让人又爱又恨的工具之一。

2025–2026 年在实际工程中,正则的使用频率其实并没有显著下降,反而因为日志解析、数据清洗、爬虫、配置文件解析、代码生成等场景,仍然是高频工具。

下面从实用角度整理一份当前最值得掌握的正则知识体系(偏向“能解决真实问题”而非“记住所有语法”)。

一、先记住这 8 种最常用的模式(占实际使用 80%+)

序号模式写法示例含义最常见使用场景Python 代码示例
1\d+一个或多个数字提取数字、ID、价格、手机号re.findall(r’\d+’, text)
2[a-zA-Z0-9_-]+常见的“单词字符”组合用户名、变量名、key、slugre.match(r’^[a-zA-Z0-9_-]+$’, username)
3[^@]+@[^@]+\.[^@]+非常粗糙但常用的邮箱校验表单校验(生产环境建议更严格)re.search(r'[^@]+@[^@]+.[^@]+’, email)
4https?://[^\s<>"']+匹配 http/https 链接从文本中提取链接re.findall(r’https?://[^\s<>”\’]+’, text)
5[\u4e00-\u9fa5]+匹配中文字符中文分词前过滤、提取中文内容re.findall(r'[\u4e00-\u9fa5]+’, text)
6(\d{4})-(\d{2})-(\d{2})捕获分组 – 日期结构化提取年月日match = re.match(r'(\d{4})-(\d{2})-(\d{2})’, s)
7(?P<year>\d{4})-(?P<month>\d{2})命名捕获组(推荐)可读性更高的分组提取match.group(‘year’), match.group(‘month’)
8.*?.*?(?=后缀)非贪婪匹配 + 正向肯定预查提取两个标记之间的内容(最实用技巧)re.search(r’start(.*?)end’, text, re.DOTALL)

二、Python 中最常用的 6 个 re 函数(记住这 6 个就够用了)

函数主要用途返回值类型是否常用典型写法示例
re.match(pattern, string)开头匹配Match 或 None★★★★re.match(r’^\d+’, line)
re.search(pattern, string)在任意位置找到第一个匹配Match 或 None★★★★★re.search(r’\d{11}’, text)
re.findall(pattern, string)找到所有非重叠匹配list[str] 或 list[tuple]★★★★★re.findall(r’\d+’, “abc123def456”) → [‘123′,’456’]
re.finditer(...)返回所有匹配的 Match 迭代器iterator[Match]★★★for m in re.finditer(r’\w+’, text): …
re.sub(pattern, repl, string)替换匹配到的内容新字符串★★★★re.sub(r’\s+’, ‘-‘, title)
re.split(pattern, string)用正则切分字符串list[str]★★★re.split(r'[,;]\s*’, “a, b;c ,d”)

三、2025–2026 年最实用的“正则三件套”写法模板

import re

# 模板1:安全提取(推荐写法)
def extract_phone(text):
    pattern = r'(?:1[3-9]\d{9})|\b0\d{2,3}[- ]?\d{7,8}\b'
    return re.findall(pattern, text)

# 模板2:命名组 + 结构化提取(日志/配置解析神器)
log_line = "2025-03-23 10:15:22 [INFO] user_id=12345 action=login ip=192.168.1.100"
pattern = r'(?P&lt;time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) \[(?P&lt;level>\w+)\] .+user_id=(?P&lt;uid>\d+)'
m = re.search(pattern, log_line)
if m:
    print(m.groupdict())   # {'time': '...', 'level': 'INFO', 'uid': '12345'}

# 模板3:非贪婪 + 预查(最常用来提取“两端之间”的内容)
html = '&lt;div class="content">重要信息在这里&lt;/div>&lt;p>其他&lt;/p>'
content = re.search(r'&lt;div class="content">(.*?)&lt;/div>', html, re.DOTALL)
print(content.group(1) if content else "未找到")

四、正则常见“优雅 vs 灾难”对比(避坑指南)

场景灾难写法(容易出问题)优雅写法(推荐)为什么更好
匹配任意字符.*.*? + re.DOTALL 或 [\s\S]*?避免贪婪匹配吃太多内容
多行匹配没加 re.DOTALLre.DOTALLre.MULTILINE. 默认不匹配换行
性能爆炸(.*)+(a?)*改用具体字符类 + 非贪婪避免灾难性回溯(catastrophic backtracking)
邮箱校验(简单版).*@.*\..*r'[^@]+@[^@]+.[^@]{2,}$’更不容易误匹配
中文 + 英文混合提取[\w\u4e00-\u9fa5]+[\w\u4e00-\u9fa5]+ + 必要时加 re.UNICODEPython 3 默认支持 Unicode

五、2026 年建议的学习 & 使用策略

  1. 前 3 周:只练最常用的 8 个模式 + 6 个函数
  2. 工具推荐
  • regex101.com(必备调试神器,选 Python flavor)
  • Pythex.org
  • VSCode 正则查找替换(直接测试)
  1. 推荐进阶顺序
  • 先掌握基础提取 → 再学替换 → 再学命名组 → 最后看零宽断言(lookaround)
  1. 生产建议
  • 能用字符串方法 / split / join 解决的,优先不用正则
  • 复杂正则一定要写注释 + 测试用例
  • 考虑用第三方库:parsimonious、re2(更快)、regex(增强版)

你现在是用正则来解决什么具体问题?
(日志解析?爬虫?数据清洗?配置读取?表单校验?……)

告诉我场景,我可以直接给你针对性的正则写法 + 测试代码。

文章已创建 5245

发表回复

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

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部