2010-09-21 18 views
9

मैं निम्नलिखित कोड का उपयोग कर रहा re.findall:re.finditer के बीच अलग-अलग व्यवहार और

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 वास्तव में दिए गए स्ट्रिंग में सभी मैच पाता है। लेकिन खोजक केवल पहला ही पाता है, केवल एक तत्व के साथ एक इटरेटर लौटाता है।

मैं खोजक और खोज कैसे कर सकता हूं वैसे ही व्यवहार करता हूं?

धन्यवाद

+0

आप इटरेटर का उपयोग कैसे कर रहे हैं, या यह निर्धारित कर रहे हैं कि यह कितने परिणाम लौटाएगा? – geoffspear

+0

मैचों में मैच के लिए और उन्हें प्रिंट करने का उपयोग कर। धन्यवाद। – simao

+0

क्या आप एक मेल बॉडी पोस्ट कर सकते हैं जिसके साथ आपको यह समस्या है? – kindall

उत्तर

20

मैं इसे यहां पुन: पेश नहीं कर सकता। पाइथन 2.7 और 3.1 दोनों के साथ कोशिश की है।

finditer और findall के बीच एक अंतर यह है कि पूर्व रिटर्न रेगेक्स मैच ऑब्जेक्ट्स जबकि अन्य मिलान किए गए कैप्चरिंग समूहों का एक टुपल लौटाता है (या यदि कोई कैप्चरिंग समूह नहीं है तो पूरा मिलान)।

तो

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

मुझे नहीं पता कि यह क्यों काम नहीं कर रहा था। मैंने पायथन 2.5 को अनइंस्टॉल किया और 2.6 तक अपग्रेड किया और यह अब काम कर रहा है: | – simao

+0

@ जेरोमजे: आपकी (अब हटाई गई) टिप्पणी के लिए धन्यवाद - आप बिल्कुल सही थे। –

4

आप उन्हें उसी तरह से व्यवहार करते हैं, क्योंकि वे अलग हैं नहीं कर सकता। क्या तुम सच में finditer से परिणामों की एक सूची बनाने के लिए चाहते हैं, तो आप एक सूची समझ इस्तेमाल कर सकते हैं:

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

सामान्य तौर पर, re.finditer द्वारा मैचों लौटे पहुँचने के लिए एक for पाश का उपयोग करें:

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

हाँ, मुझे पता है कि। समस्या यह है कि उन्हें एक ही मैच नहीं मिलते हैं। findall स्ट्रिंग में सभी मैच पाता है। खोजक केवल पहले को पाता है और हां मैंने इटरेटर में सभी तत्वों को पार करने के लिए लूप में उपयोग किया था। – simao

+6

'[पैटर्न में मिलान के लिए मैच। फाइंडिटर (मेलबॉडी)] 'सूची (पैटर्न। फिंडिटर (मेलबॉडी)) कहने का एक धीमा और कम पठनीय तरीका है' – aaronasterling

+0

धन्यवाद @ArronMcSmooth, अच्छा बिंदु। –

4

फिर से की जरूरत है। findall (pattern.string)

findall() स्ट्रिंग की एक सूची के रूप में स्ट्रिंग में पैटर्न के सभी गैर-अतिव्यापी मैचों देता है।

re.finditer()

finditer() रिटर्न प्रतिदेय वस्तु

दोनों कार्यों में, स्ट्रिंग को बाएं से दाएं स्कैन किया जाता है और मैचों को क्रम में वापस कर दिया जाता है।

संबंधित मुद्दे