在Python中,处理正则表达式的标准库是re。你可以把它想象成一把文本处理的“瑞士军刀”,专门用来在海量文本中查找、提取、替换或验证特定格式的字符串。

核心工具箱:5个最常用的方法

在使用前,记得先导入模块:import re

方法 作用 形象比喻 返回值
re.match() 从开头匹配 “必须从门口进” 匹配成功返回对象,失败返回None
re.search() 扫描全文找第一个 “在屋里找一遍,找到就停” 匹配成功返回对象,失败返回None
re.findall() 找到所有匹配项 “把所有符合条件的都抓出来” 列表 ['a', 'b', ...]
re.sub() 替换文本 “把这里的A换成B” 替换后的新字符串
re.split() 按规则分割 “按这个符号切开” 分割后的列表

代码实战:一看就懂

1. 查找与提取 (search vs findall)

如果你想提取文本中的手机号或数字:

1
2
3
4
5
6
7
8
9
10
11
12
import re

text = "我的手机号是 13800138000,备用号 13900139000"

# search: 只找第一个
res = re.search(r"\d{11}", text)
if res:
print(res.group()) # 输出: 13800138000

# findall: 找所有
all_phones = re.findall(r"\d{11}", text)
print(all_phones) # 输出: ['13800138000', '13900139000']

2. 替换 (sub)

如果你想把敏感词或者特定字符换掉:

1
2
3
4
text = "今天天气真好,今天心情不错"
# 把所有的"今天"替换成"明天"
new_text = re.sub(r"今天", "明天", text)
print(new_text) # 输出: 明天天气真好,明天心情不错

3. 验证 (match)

如果你想校验用户输入是否符合格式(比如必须以 "Hello" 开头):

1
2
3
4
text = "Hello Python"
# 必须从字符串开头匹配
if re.match(r"Hello", text):
print("验证通过")

语法速查表:正则的“单词”

正则表达式难就难在那些特殊符号。这里有一份Python中最常用的符号清单:

符号 含义 示例 匹配结果
. 匹配任意字符(除换行符) a.c "abc", "a c"
\d 匹配数字 [0-9] \d+ "123"
\w 匹配字母、数字、下划线 \w+ "user_1"
\s 匹配空白字符(空格、Tab) a\sb "a b"
^ 匹配字符串开头 ^Hello 必须以 Hello 开头
$ 匹配字符串结尾 World$ 必须以 World 结尾
* 匹配 0 次或多次 ab* "a", "ab", "abb"
+ 匹配 1 次或多次 ab+ "ab", "abb" (不含 "a")
? 匹配 0 次或 1 次 ab? "a", "ab"
{n,m} 匹配 n 到 m 次 \d{2,4} "12", "123", "1234"

两个至关重要的“潜规则”

1. 为什么要加 r 前缀?

你可能会看到很多正则都写成 r"\d+" 而不是 "\d+"

  • 原因:Python字符串本身会用 \ 转义(比如 \n 是换行)。为了避免 Python 解释器和正则引擎“打架”,我们使用原始字符串(Raw String),即在引号前加 r

  • 建议:写正则时,永远加上 r,比如 re.search(r"...", text)

2. 贪婪 vs 非贪婪

默认情况下,正则是“贪婪”的,它会尽可能多地匹配字符。

  • 贪婪模式.*

    • 匹配文本:<div>内容A</div><div>内容B</div>
    • 结果:它会一口气匹配整个字符串(因为它想匹配到最后一个 </div>)。
  • 非贪婪模式(加个 ?).*?

    • 结果:它会匹配到第一个 </div> 就停下来,分别提取出两个 div 内容。

进阶提示:预编译

如果你要在循环里大量使用同一个正则(比如处理 1 万行日志),建议先用 re.compile() 把它编译成对象,这样速度会更快。

1
2
3
4
5
6
# 预编译
pattern = re.compile(r"\d+")

# 循环使用
for line in lines:
pattern.findall(line)

总结

Python的re模块是一个功能强大的正则表达式工具,它可以帮助你快速处理各种文本操作任务。通过本文的介绍,你应该已经掌握了它的核心功能和使用技巧。

记住,正则表达式是一把双刃剑:它可以让你的代码更简洁、更高效,但也可能让你的代码变得难以理解和维护。因此,在使用正则表达式时,要注意平衡其强大功能和代码可读性之间的关系。