为什么使用正则表达式finditer()而不是findall()

时间:2016-09-10 01:50:29

标签: python regex match string-matching iterable

如果finditer()足够好,使用findall()有什么好处? findall()返回所有匹配项,而finditer()返回匹配对象,该对象无法直接作为静态列表进行处理。

例如:

import re
CARRIS_REGEX = (r'<th>(\d+)</th><th>([\s\w\.\-]+)</th>'
                r'<th>(\d+:\d+)</th><th>(\d+m)</th>')
pattern = re.compile(CARRIS_REGEX, re.UNICODE)
mailbody = open("test.txt").read()
for match in pattern.finditer(mailbody):
    print(match)
print()
for match in pattern.findall(mailbody):
    print(match)

输出:

<_sre.SRE_Match object at 0x00A63758>
<_sre.SRE_Match object at 0x00A63F98>
<_sre.SRE_Match object at 0x00A63758>
<_sre.SRE_Match object at 0x00A63F98>
<_sre.SRE_Match object at 0x00A63758>
<_sre.SRE_Match object at 0x00A63F98>
<_sre.SRE_Match object at 0x00A63758>
<_sre.SRE_Match object at 0x00A63F98>

('790', 'PR. REAL', '21:06', '04m')
('758', 'PORTAS BENFICA', '21:10', '09m')
('790', 'PR. REAL', '21:14', '13m')
('758', 'PORTAS BENFICA', '21:21', '19m')
('790', 'PR. REAL', '21:29', '28m')
('758', 'PORTAS BENFICA', '21:38', '36m')
('758', 'SETE RIOS', '21:49', '47m')
('758', 'SETE RIOS', '22:09', '68m')

我出于好奇而问这个。

2 个答案:

答案 0 :(得分:5)

finditer()返回一个迭代器,而findall()返回一个数组。迭代器仅在您通过调用.next()提出要求时才起作用。 for循环知道在迭代器上调用.next(),这意味着如果你早期从循环中break,则不会执行任何后续匹配。另一方面,阵列需要完全填充,这意味着必须预先找到每个匹配。

迭代器可以是更多的内存和CPU效率,因为它们一次只需要加载一个项目。如果您匹配一个非常大的字符串(百科全书可能是几百兆字节的文本),尝试一次查找所有匹配项可能会导致浏览器在搜索时挂起并可能耗尽内存。

答案 1 :(得分:2)

有时检索所有比赛都是多余的。如果匹配的数量非常高,你可能会冒险填满你的记忆。

使用迭代器或生成器是现代python中的一个重要概念。话虽这么说,如果你有一个小文本(例如这个网页),优化是微不足道的。

以下是有关迭代器的相关问题:Performance Advantages to Iterators?