2010-09-21 58 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()返回調用對象

在這兩個函數中,都會從左到右掃描字符串,並按照找到的順序返回 匹配項。