eagleye

Python 正则表达式的re.sub()方法详解

Python 正则表达式的re.sub()方法是用于替换字符串中匹配正则模式的子串的核心工具,其核心逻辑是:根据正则表达式匹配目标字符串中的子串,并用指定内容(字符串或函数返回值)替换这些子串。以下从功能、参数、高级用法、常见场景等维度详细解析。

一、基础语法与核心参数

re.sub()的标准语法为:

re.sub(pattern, repl, string, count=0, flags=0)

参数说明

  • pattern:正则表达式模式(必选),用于匹配需要替换的子串;
  • repl:替换内容(必选),可以是字符串函数(动态生成替换内容);
  • string:待处理的原始字符串(必选);
  • count:最多替换次数(可选),默认0表示替换所有匹配项;
  • flags:正则表达式标志(可选),如re.IGNORECASE(忽略大小写)、re.DOTALL(.匹配换行)等。

返回值:替换后的新字符串(原字符串不会被修改)。

二、repl为字符串的替换逻辑

repl是字符串时,支持通过反向引用提取匹配的子组(Group),并将其插入到替换结果中。

1. 基础替换(无反向引用)

直接用固定字符串替换所有匹配项。

示例:将字符串中的所有空格替换为下划线:

import re

text = "hello world python"

result = re.sub(r' ', '_', text) # 替换所有空格

print(result) # 输出:hello_world__python

2. 反向引用(引用匹配的子组)

若正则表达式中定义了捕获组(用()包裹的子模式),可以通过\n(n为组号)或\g<name>(命名组)引用这些组的内容到替换字符串中。

示例 1:调整日期格式

YYYY-MM-DD格式的日期替换为YYYY/MM/DD:

text = "今天是2023-10-05,明天是2023-10-06"

# 正则匹配日期(分组:年、月、日)

pattern = r'(\d{4})-(\d{2})-(\d{2})'

# 替换为:年/月/日(通过 \1、\2、\3 引用分组)

result = re.sub(pattern, r'\1/\2/\3', text)

print(result) # 输出:今天是2023/10/05,明天是2023/10/06

示例 2:命名组提高可读性

使用命名组(?P<year>\d{4})替代数字组号:

pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'

result = re.sub(pattern, r'\g<year>/\g<month>/\g<day>', text)

print(result) # 输出同上

3. 特殊字符转义

若替换字符串中需要包含反斜杠\或$(在部分正则实现中为特殊字符),需使用原始字符串或转义符\。

示例:将路径中的\替换为/(注意原始字符串的使用):

path = r'C:\Program Files\Python'

result = re.sub(r'\\', '/', path) # 正则中用 \\ 匹配实际的 \

print(result) # 输出:C:/Program Files/Python

三、repl为函数的动态替换

当替换逻辑需要根据匹配内容动态计算时(如数值转换、条件判断),可以将repl指定为一个函数。该函数接收一个匹配对象re.Match)作为参数,返回替换后的字符串。

核心逻辑

1. 正则表达式匹配到子串后,生成对应的Match对象;

2. 调用repl函数,传入该Match对象;

3. 函数返回的字符串将作为替换结果。

示例 1:将数字替换为平方值

将字符串中的每个整数替换为其平方:

import re

def square_match(match):

num = int(match.group()) # 获取匹配的数字字符串,转为整数

return str(num ** 2) # 返回平方后的字符串

text = "a=3, b=5, c=7"

result = re.sub(r'\d+', square_match, text)

print(result) # 输出:a=9, b=25, c=49

示例 2:首字母大写(条件替换)

将每个单词的首字母大写,其余字母小写(忽略缩写如HTTP):

def capitalize_word(match):

word = match.group()

# 如果单词全大写(如 HTTP),保持原样;否则首字母大写

if word.isupper():

return word

return word[0].upper() + word[1:].lower()

text = "hello world! HTTP is awesome"

result = re.sub(r'\b\w+\b', capitalize_word, text)

print(result) # 输出:Hello World! HTTP Is Awesome

四、count参数:限制替换次数

count用于指定最多替换的匹配项数量(从左到右匹配的前count个)。若count=0(默认),则替换所有匹配项。

示例:只替换前两个空格为下划线:

text = "a b c d e"

result = re.sub(r' ', '_', text, count=2) # 替换前2个空格

print(result) # 输出:a_b_c d e

五、flags参数:正则匹配模式

通过flags可以修改正则表达式的匹配规则(如忽略大小写、多行匹配等)。常见标志如下:

标志

说明

re.IGNORECASE

匹配时忽略大小写(如[A-Z]匹配任意大小写字母)

re.DOTALL

.匹配包括换行符\n在内的所有字符

re.MULTILINE

多行模式,^和$匹配行首/行尾(而非全文)

re.VERBOSE

允许正则表达式分行编写,添加注释(提高可读性)

示例:忽略大小写替换

将字符串中的python替换为Python(不区分大小写):

text = "I love Python, PYTHON is cool"

result = re.sub(r'python', 'Python', text, flags=re.IGNORECASE)

print(result) # 输出:I love Python, Python is cool

六、re.subn():返回替换次数

re.subn()是re.sub()的变体,返回一个元组(新字符串, 替换次数),适用于需要统计替换次数的场景。

示例:统计替换次数:

text = "apple, apple, banana, apple"

new_text, count = re.subn(r'apple', 'orange', text)

print(new_text) # 输出:orange, orange, banana, orange

print(count) # 输出:3(替换了3次)

七、常见应用场景

1. 数据清洗(格式化字符串)

  • 场景:调整日期、时间、电话号码等格式;
  • 示例:将2023/10/05格式的日期统一为2023-10-05:text = "日期:2023/10/05,另一个日期:2023/11/20"

result = re.sub(r'(\d{4})/(\d{2})/(\d{2})', r'\1-\2-\3', text)

print(result) # 输出:日期:2023-10-05,另一个日期:2023-11-20

2. 敏感信息脱敏(隐藏部分字符)

  • 场景:隐藏手机号、身份证号的部分数字;
  • 示例:将手机号中间4位替换为****:text = "联系电话:13812345678,备用电话:13987654321"

result = re.sub(r'(\d{3})\d{4}(\d{4})', r'\1****\2', text)

print(result) # 输出:联系电话:138****5678,备用电话:139****4321

3. 文本预处理(去除冗余内容)

  • 场景:删除多余空格、清理HTML标签;
  • 示例:删除字符串中的多个连续空格(保留单个空格):text = "hello world python"

result = re.sub(r' +', ' ', text) # 用单个空格替换多个空格

print(result) # 输出:hello world python

八、注意事项

1. 正则表达式的贪婪匹配

正则默认是贪婪匹配(尽可能匹配更长的子串),可能导致替换范围超出预期。若需非贪婪匹配,需在量词后加?(如r'<.*?>'匹配最短的 HTML 标签)。

2. 反向引用的组号有效性

若正则中未定义对应组号(如使用\3但正则只有2个组),会抛出re.error异常。

3. 函数替换的性能

当需要大量替换时,函数替换(repl为函数)的性能可能低于字符串替换,需根据场景选择。

总结

re.sub()是 Python 正则表达式中最灵活的替换工具,支持固定字符串替换、动态函数替换,可通过反向引用和标志参数实现复杂的文本处理逻辑。其核心优势在于精准匹配+灵活替换,广泛应用于数据清洗、文本预处理、日志分析等场景。掌握re.sub()的用法,能显著提升文本处理的效率和代码的健壮性。

 

posted on 2025-07-04 17:16  GoGrid  阅读(2023)  评论(0)    收藏  举报

导航