ZetCode

Python re.compile() 函数

最后修改于 2025 年 4 月 20 日

re.compile 简介

re.compile 函数是 Python re 模块的一个基本组成部分。 它将正则表达式模式转换为可以多次重用的正则表达式对象。

当重复使用相同的正则表达式时,编译模式可提供性能优势。 它还可以通过将模式定义与使用分离来使代码更具可读性。

该函数接受一个模式字符串和可选标志,并返回一个 Pattern 对象,该对象具有用于各种匹配操作的方法。

基本语法

re.compile 的语法很简单

re.compile(pattern, flags=0)

pattern 是正则表达式字符串。 可选的 flags 修改模式匹配文本的方式。

基本模式编译

让我们从编译和使用基本模式的简单示例开始。

basic_compile.py
#!/usr/bin/python

import re

text = "The quick brown fox jumps over the lazy dog"
pattern = re.compile(r'fox')

match = pattern.search(text)
if match:
    print(f"Found '{match.group()}' at position {match.start()}")

此示例演示了基本工作流程:编译模式,然后使用它来搜索文本。 原始字符串 (r'') 阻止 Python 解释反斜杠。

pattern = re.compile(r'fox')

这里我们编译一个简单的模式,该模式匹配文字字符串“fox”。 编译后的模式存储起来以供重用。

match = pattern.search(text)

我们使用编译后的模式的 search 方法来查找文本中的匹配项。 如果找到,这将返回一个匹配对象。

使用标志

标志修改模式匹配文本的方式。 让我们看看如何使用它们。

flags_example.py
#!/usr/bin/python

import re

text = "Python is FUN!"
pattern = re.compile(r'fun', re.IGNORECASE)

match = pattern.search(text)
if match:
    print(f"Found '{match.group()}' ignoring case")

re.IGNORECASE 标志使匹配不区分大小写。 其他有用的标志包括 re.MULTILINEre.DOTALL

用于提高性能的预编译模式

重用时,编译模式可提高性能。 这是一个基准。

performance.py
#!/usr/bin/python

import re
import timeit

text = "a" * 1000 + "b"
setup = "import re; text = '" + text + "'; pattern = re.compile(r'a+b')"
stmt_compiled = "pattern.search(text)"
stmt_uncompiled = "re.search(r'a+b', text)"

compiled_time = timeit.timeit(stmt_compiled, setup, number=10000)
uncompiled_time = timeit.timeit(stmt_uncompiled, setup, number=10000)

print(f"Compiled: {compiled_time:.4f}s")
print(f"Uncompiled: {uncompiled_time:.4f}s")

这显示了重复使用时,已编译和未编译模式之间的性能差异。

将编译模式与 findall 结合使用

编译模式适用于所有正则表达式函数。 这是 findall

findall_example.py
#!/usr/bin/python

import re

text = "10 apples, 20 oranges, 15 bananas, 5 pineapples"
pattern = re.compile(r'\d+')

numbers = pattern.findall(text)
print("Numbers found:", numbers)

编译后的模式从文本中提取所有数字序列。 findall 方法将所有匹配项作为列表返回。

使用编译模式拆分文本

编译模式还可以有效地拆分文本。

split_example.py
#!/usr/bin/python

import re

text = "first,second;;third|fourth\nfifth"
pattern = re.compile(r'[,;|\n]+')

parts = pattern.split(text)
print("Split result:", parts)

这将拆分逗号、分号、管道或换行符的任意组合上的文本。 + 量词处理连续分隔符。

模式替换

编译模式可以实现有效的文本替换。

sub_example.py
#!/usr/bin/python

import re

text = "Contact us at support@example.com or sales@example.org"
pattern = re.compile(r'([a-z]+)@([a-z]+)\.([a-z]{2,})')

# Replace emails with [REDACTED]
redacted = pattern.sub('[REDACTED]', text)
print(redacted)

这会找到电子邮件模式,并将其替换为占位符文本。 使用编译后的模式可以有效地执行替换。

带有组的高级模式

编译后的模式可以捕获组以进行复杂的匹配。

groups_example.py
#!/usr/bin/python

import re

text = "Date: 2023-12-25, Time: 23:59"
date_pattern = re.compile(r'Date: (\d{4})-(\d{2})-(\d{2})')
time_pattern = re.compile(r'Time: (\d{2}):(\d{2})')

date_match = date_pattern.search(text)
time_match = time_pattern.search(text)

if date_match:
    print(f"Year: {date_match.group(1)}, Month: {date_match.group(2)}")
if time_match:
    print(f"Hour: {time_match.group(1)}, Minute: {time_match.group(2)}")

这演示了如何使用命名组提取结构化数据。 编译后的模式使提取高效且易于阅读。

最佳实践

使用 re.compile 时,请遵循以下最佳实践

性能注意事项

虽然 re.compile 提供了性能优势,但它们在紧密的循环中最为明显。 对于一次性匹配,差异可以忽略不计。

Python 在内部缓存最近使用的模式,因此即使未编译的正则表达式也具有一些优化。 但是,显式编译可以提供更多的控制和清晰度。

来源

Python re.compile() 文档

本教程涵盖了 Python re.compile 函数的基本方面。 掌握模式编译将使您的正则表达式代码更有效率和更易于维护。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 到目前为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程