re.sub支持字符串、函数、对象等多种替换方式,结合分组引用、字典映射和状态管理,可高效处理文本清洗、格式转换等复杂任务。

Python 的 re.sub 不只是简单“找一个换一个”,关键在于灵活利用 替换参数的多种形态——支持字符串、函数、甚至带状态的对象,配合分组引用和条件逻辑,能解决大量文本清洗、格式转换、模板填充等实际问题。
用函数做动态替换,处理复杂逻辑
当替换内容依赖匹配结果(如大小写转换、计数、查表映射),直接传入函数比拼接字符串更清晰可靠。函数接收一个 Match 对象,返回替换字符串:
- 把所有数字加 1:
re.sub(r'd+', lambda m: str(int(m.group()) + 1), text) - 将驼峰命名转下划线(如
userName→user_name):re.sub(r'([a-z])([A-Z])', lambda m: f'{m.group(1)}_{m.group(2).lower()}', text) - 统计并标记第几次出现:
count = {'n': 0}; re.sub(r'pattern', lambda m: f'[#{(count["n"] := count["n"] + 1)}]', text)(Python 3.8+ 海象运算符)
用分组引用实现结构化重排
在替换字符串中用 、 或 g<name></name> 引用捕获组,可轻松调整顺序、补前缀后缀、或选择性保留部分内容:
- 交换日期格式
2023-04-01→01/04/2023:re.sub(r'(d{4})-(d{2})-(d{2})', r'//', date_str) - 提取邮箱用户名并加域名前缀:
re.sub(r'(w+)@(w+.w+)', r'prefix_@\2', 'alice@gmail.com')→'prefix_alice@gmail.com' - 命名组更易读:
re.sub(r'(?P<year>d{4})-(?P<month>d{2})', r'g<month>/g<year>', s)</year></month></month></year>
用字典/对象控制替换行为(避免硬编码)
把替换规则抽离到字典或类中,提升可维护性,尤其适合多规则映射或需复用逻辑的场景:
立即学习“Python免费学习笔记(深入)”;
- 用字典映射关键词:
mapping = {'cat': 'feline', 'dog': 'canine'};<br>re.sub(r'cat|dog', lambda m: mapping[m.group()], text) - 用类封装带状态的替换器(如自动编号标题):
class NumberedReplacer:
def __init__(self): self.count = 0
def __call__(self, m): self.count += 1; return f'[{self.count}] {m.group(1)}'re.sub(r'##s+(.+)', NumberedReplacer(), markdown)
注意边界与性能:避免常见坑
看似简单的 re.sub 容易因忽略细节导致意外结果:
-
贪婪 vs 非贪婪:默认贪婪匹配,
r'a.*b'在'a1b2b'中匹配整个'a1b2b';需写成r'a.*?b'才匹配'a1b' -
特殊字符转义:替换字符串中
、&、$有特殊含义,如要字面量输出反斜杠,写r'\'或'\\' -
编译正则提升性能:对高频调用,先
pat = re.compile(r'...'),再反复用pat.sub(...) -
不匹配时返回原串:
re.sub总是返回新字符串,未匹配则原样返回,无需额外判断









