2010-09-21 20 views
9

re.findall:Farklı re.finditer arasındaki davranış ve aşağıdaki kodu kullanıyorum

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) 

Ama finditer ve findall farklı şeyler buluyorlar. Findall, verilen dizedeki tüm eşleşmeleri gerçekten bulur. Ancak bulucu sadece bir tane ile bir yineleyici döndüren ilkini bulur.

Bulucu ve findayı aynı şekilde nasıl davranabilirim?

Teşekkür

+0

Yineleyiciyi nasıl kullanıyorsunuz veya kaç sonuç döndüğünü belirliyorsunuz? – geoffspear

+0

bir eşleşme eşleşmesi kullanarak ve bunları basarak. Teşekkürler. – simao

+0

Bu sorunla ilgili bir posta gövdesi gönderebilir misiniz? – kindall

cevap

20

gerçekten finditer sonuçların bir liste oluşturmak istiyorsanız, o zaman bir liste anlama kullanabilirsiniz Bunu burada üretemiyorum. Hem Python 2.7 ve 3.1 ile denediniz. finditer ve findall arasında

bir fark olduğu için diğer verir; oysa önceki döner normal ifade eşleme nesneleri eşleşen yakalama gruba demet (ya da tüm maç bir yakalama gruplar varsa).

Yani

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) 

baskılar

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

Eğer findall alıyoruz gibi finditer aynı çıktıyı istiyorsanız

, sen

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

Neden çalışmadığını bilmiyorum. Python 2.5 kaldırıldı ve 2.6 yükseltildi ve şimdi çalışıyor: | – simao

+0

@JeromeJ: (şimdi kaldırılmış) yorumunuz için teşekkürler - kesinlikle haklısınız. –

4

Onların farklı çünkü onları aynı şekilde davranır yapamazsınız. re.finditer tarafından döndürülen eşleşmeleri erişmek için bir for döngü kullanın Genelde

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

:

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

Evet, bunu biliyorum. Sorun şu ki, aynı eşleşmeleri bulamıyorlar. Findall dizede tüm maçları bulur. finditer sadece birinciyi bulur ve evet yineleyicideki tüm öğeleri geçmek için bir döngüde kullanırdım. – simao

+6

'[pattern.finditer (mailbody) eşleşmesi için eşleşme]' sadece liste (pattern.finditer (mailbody)) '' – aaronasterling

+0

Teşekkür @ArronMcSmooth, iyi nokta demenin daha yavaş ve daha okunaklı bir yoludur. –

4

yeniden gerekir. findall (pattern.string)

findall() dizeleri bir liste olarak dize desenin tüm örtüşmeyen eşleşmeleri döndürür.

re.finditer()

finditer() çağrılabilir nesne döndürür.

Her iki işlevde de, dize soldan sağa doğru taranır ve bulunan sırayla eşleşmeleri döndürülür.

İlgili konular