2010-09-21 10 views
9

ich den folgenden Code verwenden:Unterschiedliches Verhalten zwischen re.finditer und 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) 

Aber finditer und findall zu finden sind verschiedene Dinge. Findall findet tatsächlich alle Treffer in der angegebenen Zeichenfolge. Der Finder findet jedoch nur den ersten und gibt einen Iterator mit nur einem Element zurück.

Wie kann ich Finder und Findall auf die gleiche Weise verhalten?

Dank

+0

Wie verwenden Sie den Iterator oder bestimmen, wie viele Ergebnisse zurückgegeben werden? – geoffspear

+0

mit a für Übereinstimmung in Übereinstimmungen und Drucken von ihnen. Vielen Dank. – simao

+0

Können Sie einen Nachrichtentext posten, mit dem dieses Problem besteht? – kindall

Antwort

20

Ich kann das hier nicht wiedergeben. Habe es mit Python 2.7 und 3.1 versucht.

Ein Unterschied zwischen finditer und findall ist, dass erstere kehrt Regex Objekte, während die anderen kehrt ein Tupel der angepaßten einfangenden Gruppen (oder das gesamte Spiel, wenn es keine einfangenden Gruppen sind).

So

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) 

druckt

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

Wenn Sie die gleiche Ausgabe von finditer wollen, wie Sie von findall bekommen, müssen Sie

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

Ich weiß nicht, warum es nicht funktionierte. Ich habe Python 2.5 deinstalliert und auf 2.6 aktualisiert und es funktioniert jetzt: | – simao

+0

@JeromeJ: Danke für Ihren (jetzt entfernten) Kommentar - Sie hatten absolut Recht. –

4

Sie können ihnen die gleiche Art und Weise nicht machen verhalten, weil sie anders sind. Wenn Sie wirklich eine Liste der Ergebnisse von finditer erstellen möchten, dann können Sie eine Liste Verständnis verwenden:

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

In der Regel verwenden eine for Schleife, die Spiele von re.finditer zurück Zugang:

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

Ja, das weiß ich. Problem ist, sie finden nicht die gleichen Übereinstimmungen. findall findet alle Übereinstimmungen in der Zeichenfolge. finditer findet nur die erste und ja, ich habe eine For-In-Schleife benutzt, um alle Elemente im Iterator zu durchlaufen. – simao

+6

'[Übereinstimmung für pattern.finditer (mailbody)]' ist nur eine langsamere und weniger lesbare Art zu sagen 'list (pattern.finditer (mailbody))' – aaronasterling

+0

Dank @ArronMcSmooth, guter Punkt. –

4

re. findall (pattern.string)

findall() gibt alle nicht-überlappende Spiele von Muster in String als eine Liste von Strings.

re.finditer()

finditer() gibt aufrufbare Objekt.

In beiden Funktionen wird die Zeichenfolge von links nach rechts gescannt und die Übereinstimmungen werden in der angegebenen Reihenfolge zurückgegeben.

Verwandte Themen