2010-09-21 61 views
9

我使用下面的代码:不同的行为和re.findall

CARRIS_REGEX=r'<th>(\d+)</th><th>([\s\w\.\-]+)</th><th>(\d+:\d+)</th><th>(\d+m)</th>' 
pattern = re.compile(CARRIS_REGEX, re.UNICODE) 
matches = pattern.finditer(mailbody) 
findall = pattern.findall(mailbody) 

但finditer和的findall发现不同的事物。 Findall确实找到了给定字符串中的所有匹配项。但是finditer只能找到第一个,只返回一个只有一个元素的迭代器。

如何让finditer和findall的行为方式相同?

谢谢

+0

你是如何使用迭代器,或确定它将返回多少结果? – geoffspear 2010-09-21 22:43:59

+0

使用a匹配并打印它们。谢谢。 – simao 2010-09-21 22:49:53

+0

你可以发布邮件正文吗? – kindall 2010-09-21 22:58:25

回答

20

这里我无法重现。已经使用Python 2.7和3.1进行了试用。

finditerfindall之间的一个区别是,前者返回正则表达式匹配对象,而另一个返回匹配捕获组的元组(或者如果没有捕获组,则返回整个匹配)。

所以

import re 
CARRIS_REGEX=r'<th>(\d+)</th><th>([\s\w\.\-]+)</th><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') 

如果你想从finditer输出一样你从findall得到,你需要

for match in pattern.finditer(mailbody): 
    print(tuple(match.groups())) 
+0

我不知道它为什么不起作用。我卸载了python 2.5并升级到2.6,现在它正在工作:| – simao 2010-10-06 23:33:19

+0

@JeromeJ:感谢您的(现在删除的)评论 - 您说的没错。 – 2015-05-16 06:15:07

4

你不能让他们行为相同的方式,因为他们是不同的。如果你真的想从finditer创建结果列表,那么你可以使用列表理解:

>>> [match for match in pattern.finditer(mailbody)] 
[...] 

在一般情况下,使用for循环通过re.finditer访问返回的比赛:

>>> for match in pattern.finditer(mailbody): 
...  ... 
+0

是的,我知道。问题是,他们没有找到相同的匹配。 findall查找字符串中的所有匹配项。 finditer只找到第一个,是的,我用for循环遍历迭代器中的所有元素。 – simao 2010-09-21 22:48:31

+6

'[match for match in pattern.finditer(mailbody)]'只是说'list(pattern.finditer(mailbody))'的一种较慢和较不可读的方式' – aaronasterling 2010-09-21 23:40:33

+0

感谢@ArronMcSmooth,好点。 – 2010-09-22 01:57:56

4

重。的findall(pattern.string)

的findall()返回所有非重叠模式的匹配字符串 作为字符串的列表。

re.finditer()

finditer()返回调用对象

在这两个函数中,都会从左到右扫描字符串,并按照找到的顺序返回 匹配项。