为什么使用正则表达式 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 高效,因为它们一次只需要加载一个项目。如果您要匹配一个非常大的字符串(百科全书可能是几百兆字节的文本),尝试一次找到所有匹配项可能会导致浏览器在搜索时挂起并可能 运行 内存不足。
如果 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 高效,因为它们一次只需要加载一个项目。如果您要匹配一个非常大的字符串(百科全书可能是几百兆字节的文本),尝试一次找到所有匹配项可能会导致浏览器在搜索时挂起并可能 运行 内存不足。