Python re.finditer() 函数
最后修改于 2025 年 4 月 20 日
re.finditer 简介
re.finditer
函数是 Python 的 re
模块中用于模式匹配的强大工具。 它返回一个迭代器,为所有非重叠匹配生成匹配对象。
与返回字符串的 re.findall
不同,finditer
提供带有详细匹配信息的匹配对象。 这包括位置和捕获组。
该函数对于大型文本具有内存效率,因为它以惰性方式处理匹配。 当您需要匹配详细信息而不仅仅是文本时,它是理想的选择。
基本语法
re.finditer
的语法很简单
re.finditer(pattern, string, flags=0)
pattern
是要匹配的正则表达式。 string
是要搜索的文本。 可选的 flags
修改匹配行为。
基本模式匹配
让我们从一个简单的例子开始,找到文本中的所有元音。
#!/usr/bin/python import re text = "The quick brown fox jumps over the lazy dog" pattern = r'[aeiou]' for match in re.finditer(pattern, text): print(f"Found '{match.group()}' at position {match.start()}")
此示例查找文本中的所有元音并打印每个元音及其位置。 匹配对象提供 group
和 start
方法。
pattern = r'[aeiou]'
此模式匹配任何单个元音字符。 方括号定义一个字符类。
for match in re.finditer(pattern, text):
finditer
调用返回一个匹配对象的迭代器。 我们循环遍历它们以处理每个匹配。
查找具有特定模式的单词
让我们在文本中查找所有以“q”或“j”开头的单词。
#!/usr/bin/python import re text = "The quick brown fox jumps over the lazy dog" pattern = r'\b[qj]\w+\b' for match in re.finditer(pattern, text, re.IGNORECASE): print(f"Found word: {match.group()}") print(f"Start: {match.start()}, End: {match.end()}")
这使用单词边界 (\b
) 来匹配整个单词。 \w+
匹配后续的单词字符。
re.IGNORECASE
标志使匹配不区分大小写。 匹配对象提供开始和结束位置。
提取电子邮件地址
以下是如何从文本中提取电子邮件地址,并显示详细位置。
#!/usr/bin/python import re text = "Contact us at support@example.com or sales@example.org" pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' for match in re.finditer(pattern, text): print(f"Email: {match.group()}") print(f"Position: {match.span()}") print(f"Full match: {text[match.start():match.end()]}")
此模式匹配标准电子邮件格式。 span
方法返回一个 (start, end) 位置的元组。
我们演示了如何通过 match.group() 和切片原始字符串来访问匹配的文本。
查找带有分组的日期
此示例提取日期,同时捕获日、月和年组。
#!/usr/bin/python import re text = "Dates: 2023-12-25, 2024-01-01, 2024-02-14" pattern = r'(\d{4})-(\d{2})-(\d{2})' for match in re.finditer(pattern, text): print(f"Full date: {match.group(0)}") print(f"Year: {match.group(1)}, Month: {match.group(2)}") print(f"Day: {match.group(3)} at {match.start()}")
括号创建捕获组。 组 0 始终是完整匹配。 后续组匹配带括号的子模式。
这对于结构化数据提取非常有用,您既需要完整匹配及其组成部分。
使用先行断言的重叠匹配
finditer
通常查找非重叠匹配。 这是使用先行断言查找重叠的方法。
#!/usr/bin/python import re text = "abracadabra" pattern = r'(?=(\w{3}))' # Lookahead for 3-letter sequences for match in re.finditer(pattern, text): print(f"Found: {match.group(1)} at {match.start()}")
正向先行断言 (?=...)
允许查找重叠匹配。 实际匹配在组 1 中捕获。
此技术对于查找文本中所有可能的 n-gram 或滑动窗口很有用。
多行文本处理
此示例演示了如何处理带有行号的多行文本。
#!/usr/bin/python import re text = """First line Second line with IMPORTANT data Third line Fourth line with CRITICAL information""" pattern = r'(IMPORTANT|CRITICAL)' lines = text.splitlines() for match in re.finditer(pattern, text): line_no = text[:match.start()].count('\n') + 1 print(f"Found '{match.group()}' in line {line_no}:") print(f"> {lines[line_no-1]}")
我们通过计算匹配项之前的新行来计算行号。 实际的行内容是从预先分割的列表中检索的。
这种方法对于日志处理或文档分析非常有用,其中行上下文很重要。
性能注意事项
使用 re.finditer
处理大型文本时,请考虑以下性能提示
- 如果经常重复使用,请预编译模式 (
re.compile
) - 尽可能使用更简单的模式 - 复杂的正则表达式速度较慢
- 在找到匹配项后立即处理它们,而不是首先收集所有匹配项
- 考虑使用字符串方法进行简单的固定字符串搜索
- 注意复杂模式中的灾难性回溯
来源
本教程介绍了 Python 的 re.finditer
函数的本质方面。 掌握这种基于迭代器的方法将使您的模式匹配代码更加高效和灵活。
作者
列出所有 Python 教程。