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

Why use regex finditer() rather than findall()

如果 findall() 足够好,使用 finditer() 有什么好处? findall() returns 全部匹配,而 finditer() returns 匹配不能像静态列表那样直接处理的对象。

例如:

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')

我出于好奇问这个。

有时检索所有匹配项是多余的。如果匹配项的数量非常多,您可能会冒着加载所有匹配项填满内存的风险。

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

这是一个关于迭代器的相关问题:Performance Advantages to Iterators?

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

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