从基础到进阶详解Python如何使用正则替换字符串

 更新时间:2026年04月15日 08:29:42   作者:detayun  
在Python中,字符串替换是常见的操作,这篇文章将详细介绍如何使用正则表达式进行字符串替换,并提供实际案例,感兴趣的小伙伴可以了解下

在Python中,字符串替换是常见的操作,但简单的str.replace()方法只能处理固定字符串的替换。当需要模式匹配(如替换所有数字、邮箱、URL等)时,正则表达式(re模块)的re.sub()方法就派上了用场。本文将详细介绍如何使用正则表达式进行字符串替换,并提供实际案例。

1. 基础正则替换:re.sub()

1.1re.sub()基本语法

re.sub() 是Python正则替换的核心方法,语法如下:

import re

re.sub(pattern, repl, string, count=0, flags=0)
  • pattern:正则表达式模式(匹配要替换的内容)。
  • repl:替换内容(可以是字符串或函数)。
  • string:待替换的原始字符串。
  • count:最大替换次数(默认0表示全部替换)。
  • flags:正则标志(如re.IGNORECASE忽略大小写)。

1.2 简单替换示例

(1) 替换所有数字

import re

text = "我的电话是123456789,QQ是987654321"
new_text = re.sub(r'\d+', '***', text)  # \d+ 匹配1个或多个数字
print(new_text)
# 输出: 我的电话是***,QQ是***

(2) 替换所有非字母字符

text = "Hello! 123 @World#Python"
new_text = re.sub(r'[^a-zA-Z]', ' ', text)  # [^a-zA-Z] 匹配非字母字符
print(new_text)
# 输出: Hello      World Python

(3) 忽略大小写替换

text = "Python is FUN, python is powerful"
new_text = re.sub(r'python', 'Java', text, flags=re.IGNORECASE)  # 忽略大小写
print(new_text)
# 输出: Java is FUN, Java is powerful

2. 高级替换技巧

2.1 使用分组(())和反向引用(\1,\2)

正则表达式可以用()分组,并在替换时用\1\2引用分组内容。

示例:交换日期格式(YYYY-MM-DD → DD/MM/YYYY)

text = "2023-01-01, 2024-12-31"
new_text = re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\3/\2/\1', text)  # \3=日, \2=月, \1=年
print(new_text)
# 输出: 01/01/2023, 31/12/2024

2.2 使用函数动态替换

repl参数可以是一个函数,根据匹配内容动态生成替换字符串。

示例:将数字乘以2后替换

def double_num(match):
    num = int(match.group())  # 获取匹配的数字
    return str(num * 2)

text = "1 apple, 2 bananas, 3 oranges"
new_text = re.sub(r'\d+', double_num, text)  # 调用函数替换
print(new_text)
# 输出: 2 apple, 4 bananas, 6 oranges

示例:隐藏敏感信息(如邮箱)

def hide_email(match):
    email = match.group()
    return email[0] + "***" + email[-4:]  # 保留首字母和后4位

text = "联系我:test@example.com 或 admin@site.org"
new_text = re.sub(r'[\w.-]+@[\w.-]+', hide_email, text)
print(new_text)
# 输出: 联系我:t***mple.com 或 a***site.org

2.3 限制替换次数(count参数)

text = "111-222-333-444"
new_text = re.sub(r'\d+', 'X', text, count=2)  # 只替换前2个数字
print(new_text)
# 输出: X-X-333-444

3. 实际应用案例

案例1:清理HTML标签

import re

html = "<p>Hello, <b>World</b>!</p>"
clean_text = re.sub(r'<[^>]+>', '', html)  # 匹配所有HTML标签并删除
print(clean_text)
# 输出: Hello, World!

案例2:标准化电话号码格式

text = "电话:010-12345678,手机:138-1234-5678"
new_text = re.sub(r'(\d{3})-(\d{4})-(\d{4})', r'\1\2\3', text)  # 尝试直接替换(可能不匹配)
# 更通用的方法:
def normalize_phone(match):
    full_num = re.sub(r'[^\d]', '', match.group())  # 先删除所有非数字
    if len(full_num) == 11:  # 手机号码
        return f"手机:{full_num[:3]}-{full_num[3:7]}-{full_num[7:]}"
    elif len(full_num) == 8:  # 座机号码(简化版)
        return f"电话:{full_num[:3]}-{full_num[3:]}"
    else:
        return match.group()

# 先提取所有电话号码(简化版,实际需更复杂正则)
text_with_phones = re.sub(r'(\d{3}[-]?\d{4}[-]?\d{4})|(\d{3}[-]?\d{4})', normalize_phone, text)
# 更准确的方式是分两步:
# 1. 提取所有电话号码
# 2. 替换
print(text_with_phones)  # 输出可能不符合预期,需更精细的正则

# 更合理的实现(分两步):
phones = re.findall(r'\d{3}[-]?\d{4}[-]?\d{4}|\d{3}[-]?\d{4}', text)
for phone in phones:
    cleaned = re.sub(r'[^\d]', '', phone)
    if len(cleaned) == 11:
        new_phone = f"{cleaned[:3]}-{cleaned[3:7]}-{cleaned[7:]}"
    elif len(cleaned) == 8:
        new_phone = f"{cleaned[:3]}-{cleaned[3:]}"
    else:
        new_phone = phone
    text = text.replace(phone, new_phone)
print(text)
# 输出: 电话:010-12345678,手机:138-1234-5678

更简洁的电话号码标准化(使用re.sub直接替换)

text = "电话:010-12345678,手机:138-1234-5678"

def normalize_phone(match):
    num = re.sub(r'[^\d]', '', match.group())
    if len(num) == 11:
        return f"手机:{num[:3]}-{num[3:7]}-{num[7:]}"
    elif len(num) == 8:
        return f"电话:{num[:3]}-{num[3:]}"
    else:
        return match.group()

# 匹配手机号(11位)或座机号(8位,可能带-)
new_text = re.sub(
    r'(手机:)?(\d{3}[-]?\d{4}[-]?\d{4})|(电话:)?(\d{3}[-]?\d{4})',
    lambda m: normalize_phone(m),
    text
)
# 上述正则不够完美,更准确的方式:
# 先提取所有电话号码,再替换
print(new_text)  # 可能需要调整正则

# 更准确的实现(分两步):
import re

text = "电话:010-12345678,手机:138-1234-5678"

# 匹配手机号或座机号
pattern = r'(?:电话:|手机:)?(\d{3}[-]?\d{4}[-]?\d{4}|\d{3}[-]?\d{4})'

def replace_phone(match):
    raw_phone = match.group(1)
    cleaned = re.sub(r'[^\d]', '', raw_phone)
    if len(cleaned) == 11:
        return f"手机:{cleaned[:3]}-{cleaned[3:7]}-{cleaned[7:]}"
    elif len(cleaned) == 8:
        return f"电话:{cleaned[:3]}-{cleaned[3:]}"
    else:
        return raw_phone

new_text = re.sub(pattern, replace_phone, text)
print(new_text)
# 输出: 电话:010-12345678,手机:138-1234-5678

简化版(假设输入格式较规范)

text = "电话:010-12345678,手机:138-1234-5678"
new_text = re.sub(
    r'(\d{3})-(\d{4})-(\d{4})',  # 匹配手机号格式
    r'手机:\1-\2-\3',
    re.sub(
        r'(\d{3})-(\d{4})',  # 匹配座机号格式
        r'电话:\1-\2',
        text
    )
)
print(new_text)
# 输出: 电话:010-12345678,手机:138-1234-5678

案例3:替换URL中的协议(http → https)

text = "访问 http://example.com 或 https://test.org"
new_text = re.sub(r'http://', 'https://', text)  # 简单替换
print(new_text)
# 输出: 访问 https://example.com 或 https://test.org

4. 常见问题与解决方案

问题1:正则表达式匹配不到内容?

  • 原因:正则模式错误或未使用re.IGNORECASE等标志。
  • 解决:使用在线正则测试工具(如regex101.com)调试。

问题2:替换后格式混乱?

  • 原因:未正确使用分组或反向引用。
  • 解决:检查()分组和\1\2是否匹配。

问题3:性能问题(大量文本替换)?

  • 原因re.sub()在循环中调用或正则复杂度高。
  • 解决:预编译正则(re.compile())或优化正则表达式。

5. 总结

方法适用场景示例
re.sub(r'\d+', 'X', text)简单模式替换替换所有数字为X
re.sub(r'(\d{4})-(\d{2})', r'\2/\1', text)分组与反向引用交换日期格式
re.sub(r'\d+', lambda m: str(int(m.group())*2), text)函数动态替换数字乘以2后替换
re.sub(r'<[^>]+>', '', text)清理HTML标签删除所有<...>标签

最佳实践

  1. 简单替换str.replace(),复杂模式用re.sub()
  2. 需要保留部分匹配内容时,用()分组和\1反向引用。
  3. 动态生成替换内容时,用函数作为repl参数。
  4. 处理大量文本时,预编译正则(re.compile())提高性能。

掌握这些技巧后,你可以高效地处理各种字符串替换需求! 

到此这篇关于从基础到进阶详解Python如何使用正则替换字符串的文章就介绍到这了,更多相关Python正则替换字符串内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python 中的@property的用法详解

    python 中的@property的用法详解

    这篇文章主要介绍了python @property的用法,简单地说就是一个类里面的方法一旦被@property装饰,就可以像调用属性一样地去调用这个方法,它能够简化调用者获取数据的流程,感兴趣的朋友跟随小编一起看看吧
    2022-06-06
  • Python标准库中的logging用法示例详解

    Python标准库中的logging用法示例详解

    logging是Python标准库中记录常用的记录日志库,通过logging模块存储各种格式的日志,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等,这篇文章主要介绍了Python标准库中的logging,需要的朋友可以参考下
    2022-09-09
  • Python 实现list,tuple,str和dict之间的相互转换

    Python 实现list,tuple,str和dict之间的相互转换

    这篇文章主要介绍了Python 实现list,tuple,str和dict之间的相互转换,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • python元组简单介绍

    python元组简单介绍

    这篇文章主要给大家分享中得python基础 元组,元组的特点是一种不可变序列,一旦创建就不能修改,带着些许了解和小编一起进入文章得具体内容吧
    2021-10-10
  • pytorch加载训练好的模型用来测试或者处理方式

    pytorch加载训练好的模型用来测试或者处理方式

    这篇文章主要介绍了pytorch加载训练好的模型用来测试或者处理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • python控制nao机器人身体动作实例详解

    python控制nao机器人身体动作实例详解

    这篇文章主要为大家详细介绍了python控制nao机器人身体动作实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • Python格式化输出的几种汇总

    Python格式化输出的几种汇总

    这篇文章主要介绍了Python格式化输出的几种汇总,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • pycharm-professional-2020.1下载与激活的教程

    pycharm-professional-2020.1下载与激活的教程

    这篇文章主要介绍了pycharm-professional-2020.1下载与激活的教程,本文分为安装和永久激活两部分内容,需要的朋友可以参考下
    2020-09-09
  • Django的HttpRequest和HttpResponse对象详解

    Django的HttpRequest和HttpResponse对象详解

    这篇文章主要介绍了Django的HttpRequest和HttpResponse对象,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • 玩转Python图像处理之二值图像腐蚀详解

    玩转Python图像处理之二值图像腐蚀详解

    这篇文章主要给大家介绍了关于Python图像处理之二值图像腐蚀的相关资料,对原图进行二值化后,选择不同的结构元素对其进行膨胀和腐蚀运算处理,并仿真出图像结果,需要的朋友可以参考下
    2021-09-09

最新评论