Python正则替换文本:从入门到精通的6个实战案例
目录导读
- 为什么正则替换是文本处理的利器?
- Python正则替换核心函数详解
- 实战案例一:清除HTML标签
- 实战案例二:统一日期格式
- 实战案例三:敏感词过滤与替换
- 实战案例四:批量重命名变量名
- 实战案例五:格式化电话号码
- 实战案例六:多模式复合替换(进阶技巧)
- 高频问答与避坑指南
为什么正则替换是文本处理的利器?
在Python数据处理、爬虫清洗、日志分析或代码重构中,正则替换(Regex Substitution) 是最基础也最强大的文本操作之一,与简单的字符串.replace()不同,正则替换允许你:

- 匹配模式而非固定字符串
- 保留匹配部分并重组成新文本
- 实现条件替换、循环替换等复杂逻辑
根据Stack Overflow 2023开发者调查,超过70%的Python开发者日常使用正则表达式处理文本。掌握re.sub(),你就掌握了对任意文本结构的“手术刀”。
Python正则替换核心函数详解
re.sub()函数是正则替换的核心,其语法为:
re.sub(pattern, repl, string, count=0, flags=0)
pattern:正则模式字符串repl:替换字符串或可调用对象(函数)string:待处理文本count:最大替换次数,0表示全部替换flags:修饰符,如re.I忽略大小写
关键技巧:在repl中使用\1、\2可以引用分组匹配的内容,例如r'\1_\2'会将匹配的两组用下划线连接。
实战案例一:清除HTML标签
场景:从HTML页面提取纯文本内容。
import re html = '<p style="color:red">Hello <b>World</b>!</p>' clean_text = re.sub(r'<[^>]+>', '', html) print(clean_text) # 输出: Hello World!
原理:<[^>]+>匹配所有以<开头、>结尾的标签,注意:这适用于简单标签,对嵌套标签请用BeautifulSoup。
实战案例二:统一日期格式
场景:将“2023-12-25”或“2023/12/25”统一为“2023年12月25日”。
text = "日期1: 2023-12-25, 日期2: 2024/01/15"
pattern = r'(\d{4})[-/](\d{2})[-/](\d{2})'
replacement = r'\1年\2月\3日'
result = re.sub(pattern, replacement, text)
print(result) # 输出: 日期1: 2023年12月25日, 日期2: 2024年01月15日
注意:分组捕获数字,\1、\2、\3分别引用第一个、第二个、第三个分组。
实战案例三:敏感词过滤与替换
场景:将用户评论中的敏感词替换为“***”。
bad_words = ['暴力', '色情', '赌博'] text = "这个电影包含暴力镜头和色情内容" pattern = '|'.join(bad_words) # 构建:暴力|色情|赌博 result = re.sub(pattern, '***', text) print(result) # 输出: 这个电影包含***镜头和***内容
进阶技巧:忽略大小写:
result = re.sub(pattern, '***', text, flags=re.I)
为什么用连接:正则中的表示“或”,能同时匹配多个敏感词。
实战案例四:批量重命名变量名
场景:将Python代码中所有下划线命名(snake_case)转为驼峰命名(camelCase)。
code = "user_name = get_user_data(user_id)"
def to_camel(match):
return match.group(1) + match.group(2).upper()
result = re.sub(r'(_)([a-z])', to_camel, code)
print(result) # 输出: userName = getUserData(userId)
核心:这里使用了可调用对象作为repl。match.group(1)是下划线,group(2)是小写字母,将其转为大写后拼接。
实战案例五:格式化电话号码
场景:将各种混乱的电话号格式统一为“XXX-XXX-XXXX”。
phones = ["13812345678", "010-12345678", "0755 1234567"]
pattern = r'(\d{3,4})[- ]?(\d{3,4})[- ]?(\d{4})'
for phone in phones:
formatted = re.sub(pattern, r'\1-\2-\3', phone)
print(formatted) # 输出: 138-1234-5678, 010-1234-5678, 0755-123-4567
注意:匹配一个可选的分隔符(连字符或空格),{3,4}表示匹配3或4位数字。
实战案例六:多模式复合替换(进阶技巧)
场景:同时去除空格、统一换行符、清理特殊符号。
text_with_garbage = "Hello world!\nThis\tis a \r\ntest." # 步骤1:多个替换用正则一次完成 result = re.sub(r'\s+', ' ', text_with_garbage) # 所有空白(空格、Tab、换行)变成单个空格 result = re.sub(r'[!@#\$%\^&\*]', '', result) # 去掉特殊符号 print(result) # 输出: Hello world This is a test.
性能提示:对于大量文本,尽量用一次re.sub完成多个替换,或者使用re.compile()预编译模式:
compiled = re.compile(r'\s+')
result = compiled.sub(' ', huge_text)
高频问答与避坑指南
Q1:re.sub和字符串replace哪个更快?
A:对于固定字符串替换,replace快3-5倍,但对于模式匹配(如“将所有日期格式统一”),只能用re.sub,建议:简单替换用replace,复杂匹配用正则。
Q2:替换时遇到转义问题怎么办?
A:使用原始字符串r'...'避免Python转义,例如r'\d'表示数字,而不是\d作为转义序列,这是新手最容易犯的错误。
Q3:如何只替换前N次?
A:设置count参数,如re.sub(pattern, repl, text, count=2)只替换前2处匹配。
Q4:正则替换中如何保留匹配部分?
A:用分组捕获要保留的部分,然后在repl中通过\1引用。
re.sub(r'(hello) world', r'\1 python', "hello world") # 输出: hello python
Q5:有没有图形化工具辅助写正则? A:推荐在线工具regex101.com(中文版也有),实时测试并解释匹配过程,但注意不要直接在爬虫中使用未测试的正则,容易触发回溯灾难。
Q6:多行文本如何处理?
A:使用re.MULTILINE(或re.M)标志,使和匹配每行的开头和结尾。
Q7:替换时出现“无效转义”错误?
A:通常是因为未使用r前缀,例如re.sub('\n', '', text)与re.sub(r'\n', '', text)不同:前者匹配一个换行符,后者匹配反斜杠加n字符串。
Q8:怎么实现逆向替换(不匹配的替换)?
A:使用负向先行断言,例如将“不是数字”的部分替换为空格:re.sub(r'(?!\d).', ' ', "abc123"),结果:123(前三个字母被替换)。
文章总结:正则替换是Python文本处理中的核心技能,掌握re.sub()的五个关键参数——模式、替换内容、目标字符串、替换次数、修饰符——就能应对90%的日常场景,从案例一到六,我们逐步覆盖了从基础HTML清理到高级代码重构的完整链路,最后提醒:写复杂正则时,务必先用小样本测试,避免生产环境出现“奇怪”的替换结果,如果遇到特殊字符或Unicode问题,在模式前加u前缀或使用re.UNICODE标志。