查看: 145|回复: 3

Python re模块实战:正则表达式字符串匹配与替换详解

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
正则表达式在Python字符串处理中扮演着核心角色,尤其在搜索、替换和分割场景下效率极高。Python内置的re模块封装了所有相关功能。本文结合实例,系统讲解如何使用re模块进行字符串的匹配与替换操作,涵盖re.sub、re.search、re.match、替换函数、多模式替换、贪婪与非贪婪以及忽略大小写等技巧。

## 一、导入re模块与基础函数

使用正则表达式前必须导入re模块:
  1. import re
复制代码

## 二、re.sub():字符串替换

re.sub()用于替换字符串中所有匹配模式的部分。语法如下:
  1. re.sub(pattern, repl, string, count=0, flags=0)
复制代码
参数说明:
- pattern:正则表达式模式(常使用原始字符串r"..."避免转义问题)。
- repl:替换字符串或替换函数。
- string:原始字符串。
- count:最大替换次数,默认0表示全部替换。
- flags:匹配模式,如忽略大小写。

示例:将"java script"替换为"javascript":
  1. text = "java script is awesome."
  2. pattern = r"\bjava script\b"
  3. repl = "javascript"
  4. new_text = re.sub(pattern, repl, text)
  5. print(new_text)  # 输出: javascript is awesome.
复制代码

再如,将所有连续4位数字替换为"****":
  1. text = "1234 hello 5678 world"
  2. pattern = r"\b\d{4}\b"
  3. repl = "****"
  4. new_text = re.sub(pattern, repl, text)
  5. print(f'Original: {text}')
  6. print(f'Replaced: {new_text}')
  7. # Original: 1234 hello 5678 world
  8. # Replaced: ****hello**** world
复制代码

## 三、re.search() 与 re.match():字符串匹配

re.search()扫描整个字符串,返回第一个匹配结果(Match对象);re.match()只从字符串开头匹配。语法:
  1. re.search(pattern, string, flags=0)
  2. re.match(pattern, string, flags=0)
复制代码

示例:检查字符串是否包含"World":
  1. text = "Hello World"
  2. pattern = r"World"
  3. match = re.search(pattern, text)
  4. if match:
  5.     print("匹配成功", match.group())  # 输出: World
复制代码

re.match()示例:检查字符串是否以"Hello"开头:
  1. text = "Hello World"
  2. pattern = r"Hello"
  3. match = re.match(pattern, text)
  4. if match:
  5.     print("匹配成功", match.group())  # 输出: Hello
复制代码
注意:re.match()若开头不匹配则返回None,而re.search()会继续向后寻找。

## 四、使用替换函数实现动态替换

当替换内容依赖于匹配结果时,可传入一个函数作为repl。函数接收Match对象,返回替换字符串。

示例:将字符串中所有数字替换为两倍数值:
  1. text = "The numbers are 123 and 456."
  2. pattern = r"\d+"
  3. def double(match):
  4.     num = int(match.group())
  5.     return str(num * 2)
  6. new_text = re.sub(pattern, double, text)
  7. print(new_text)  # 输出: The numbers are 246 and 912.
复制代码

## 五、多模式替换(字典驱动)

若需将多个特定单词逐一替换,可使用字典定义规则并利用正则的“或”模式。为避免特殊字符干扰,先用re.escape转义键。

示例:
  1. text = "apple banana cherry"
  2. rep = {"apple": "orange", "banana": "grape"}
  3. rep_escaped = dict((re.escape(k), v) for k, v in rep.items())
  4. pattern = re.compile("|".join(rep_escaped.keys()))
  5. new_text = pattern.sub(lambda m: rep_escaped[re.escape(m.group(0))], text)
  6. print(new_text)  # 输出: orange grape cherry
复制代码

## 六、贪婪匹配与非贪婪匹配

默认量词(如*、+、{})是贪婪的,会尽可能匹配更多字符;在量词后加?可启用非贪婪模式。

示例:从HTML标签内提取标题内容:
  1. text = "<title>Example</title> <body>Content</body>"
  2. # 贪婪匹配 (.*) 会匹配到最后一个闭合标签
  3. pattern_greedy = r"<title>(.*)</title>"
  4. match_greedy = re.search(pattern_greedy, text)
  5. if match_greedy:
  6.     print("贪婪结果:", match_greedy.group(1))
  7.     # 输出: Example</title> <body>Content
  8. # 非贪婪匹配 (.*?) 只匹配最近的一个
  9. pattern_non_greedy = r"<title>(.*?)</title>"
  10. match_non_greedy = re.search(pattern_non_greedy, text)
  11. if match_non_greedy:
  12.     print("非贪婪结果:", match_non_greedy.group(1))
  13.     # 输出: Example
复制代码

## 七、忽略大小写匹配

设置flags参数为re.IGNORECASE(或re.I)即可忽略大小写。

示例:
  1. text = "Hello World"
  2. pattern = r"hello"
  3. match = re.search(pattern, text, re.IGNORECASE)
  4. if match:
  5.     print("匹配成功", match.group())  # 输出: Hello
复制代码

## 八、总结

Python的re模块提供了灵活且高效的正则表达式接口。re.sub()可完成直接替换或动态替换,re.search()与re.match()负责查找,结合捕获组、量词模式和标志位,能应对绝大多数字符串处理需求。掌握这些核心用法,可极大提升文本处理的准确性与效率。实际开发中建议优先使用原生字符串定义模式,并注意贪婪与非贪婪的选择,避免匹配越界。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python re模块实战:正则表达式字符串匹配与替换详解

感谢楼主的详细讲解,非常实用!特别是多模式替换和替换函数的部分,让我对 re.sub 的灵活性有了更深的理解。有个小问题想请教:在字典驱动的替换中,如果某个键包含正则特殊字符(比如点号),re.escape 能完美处理吗?还是说需要额外注意什么?期待楼主的进一步解答!
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python re模块实战:正则表达式字符串匹配与替换详解

感谢楼主的详细讲解!一直对`re.sub`的替换函数用法不太熟,看完这篇终于明白了动态替换的逻辑,`match.group()`和`return str(num*2)`那段示例特别直观。另外想请教一下:如果替换函数需要根据匹配位置做不同处理(比如只在偶数位置的数字翻倍),有没有简洁的实现方式?
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python re模块实战:正则表达式字符串匹配与替换详解

非常感谢楼主的详细教程!正则表达式一直是我觉得比较难啃的部分,这篇把 re.sub、re.search、多模式替换和贪婪非贪婪的例子都讲得很清楚,尤其是字典驱动的多模式替换那部分,之前我一直用循环一个个替换,效率很低,这个思路确实更优雅。 想请教一下:在使用替换函数处理较大文本时,re.sub 内部是逐匹配调用的,如果匹配项非常多(比如十万个数字),函数的频繁调用会不会有明显的性能开销?有没有办法预编译模式或者缓存来优化?希望不吝赐教。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-29 13:59 , Processed in 0.041731 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部