从基础到进阶详解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 20行简单实现有道在线翻译的详解

    Python 20行简单实现有道在线翻译的详解

    这篇文章主要介绍了Python实现有道在线翻译的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • 用Python每天自动给女友免费发短信

    用Python每天自动给女友免费发短信

    大家好,本篇文章主要讲的是用Python每天自动给女友免费发短信,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • Python迭代和迭代器详解

    Python迭代和迭代器详解

    本篇文章主要介绍Python的迭代和迭代器,可迭代对象的相关概念,有需要的小伙伴可以参考下
    2016-11-11
  • Python数据类转换为JSON的常用方法总结

    Python数据类转换为JSON的常用方法总结

    这篇文章主要介绍了四种将Python自定义数据类实例转换为JSON的优雅方法,包括手动转换、自定义JSONEncoder、封装工具函数和使用pydantic,针对不同场景提供了详细实现和解释,需要的朋友可以参考下
    2026-01-01
  • python  ceiling divide 除法向上取整(或小数向上取整)的实例

    python ceiling divide 除法向上取整(或小数向上取整)的实例

    今天小编就为大家分享一篇python ceiling divide 除法向上取整 (或小数向上取整)的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • 解锁Python中神器vars内置函数的使用

    解锁Python中神器vars内置函数的使用

    vars()函数是一个内置函数,用于返回对象的__字典__,其中包含对象的__属性__,本文主要为大家详细介绍了vars()函数的具体使用,需要的小伙伴可以了解下
    2023-11-11
  • python通过http上传文件思路详解

    python通过http上传文件思路详解

    这篇文章主要介绍了python通过http上传文件,在post请求中,用files参数来接受文件对象相关的参数,通过data/json参数接受post请求体的其他参数
    2021-07-07
  • 讲解Python的Scrapy爬虫框架使用代理进行采集的方法

    讲解Python的Scrapy爬虫框架使用代理进行采集的方法

    这篇文章主要介绍了讲解Python的Scrapy爬虫框架使用代理进行采集的方法,并介绍了随机使用预先设好的user-agent来进行爬取的用法,需要的朋友可以参考下
    2016-02-02
  • Python实现简单的用户交互方法详解

    Python实现简单的用户交互方法详解

    这篇文章给大家分享了关于Python实现简单的用户交互的相关知识点内容,有需要的朋友们可以学习下。
    2018-09-09
  • Python matplotlib可视化绘图详解

    Python matplotlib可视化绘图详解

    这篇文章主要介绍了Python matplotlib绘图可视化知识点整理(小结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-09-09

最新评论