2012-06-19 7 views
5

में सफल regex मैचों से एक शब्दकोश बनाएं I Python के लिए बहुत नया है, और मैं एक फ़ाइल को पार्स करने की कोशिश कर रहा हूं। फ़ाइल में केवल कुछ पंक्तियों में ब्याज का डेटा होता है, और मैं फ़ाइल में मान्य मिलान लाइनों से पार्स की गई सामग्री के शब्दकोश के साथ समाप्त करना चाहता हूं।पाइथन

नीचे दिया गया कोड काम करता है, लेकिन यह थोड़ा बदसूरत है और मैं यह सीखने की कोशिश कर रहा हूं कि इसे कैसे किया जाना चाहिए, शायद समझ के साथ, या अन्यथा एक मल्टीलाइन रेगेक्स के साथ। मैं पायथन 3.2 का उपयोग कर रहा हूँ।

file_data = open('x:\\path\\to\\file','r').readlines() 
my_list = [] 
for line in file_data: 
    # discard lines which don't match at all 
    if re.search(pattern, line): 
     # icky, repeating search!! 
     one_tuple = re.search(pattern, line).group(3,2) 
     my_list.append(one_tuple) 
my_dict = dict(my_list) 

क्या आप बेहतर कार्यान्वयन का सुझाव दे सकते हैं?

+2

समझें सुंदर हो सकती हैं, लेकिन आप आसानी से चर के अंदर एक मूल्य को बाध्य नहीं कर सकते हैं, इसलिए आपको डबल 're.search' की आवश्यकता होगी। बस एक लूप का उपयोग करें। –

उत्तर

4

उत्तर के लिए धन्यवाद। उन्हें एक साथ रखने के बाद मुझे

file_data = open('x:\\path\\to\\file','r').read() 
my_list = re.findall(pattern, file_data, re.MULTILINE) 
my_dict = {c:b for a,b,c in my_list} 

लेकिन मुझे नहीं लगता कि मैं सहायता के बिना आज वहां पहुंच सकता था।

+2

आप समझने के चरण को छोड़ने के लिए पहले समूह को गैर-कैप्चरिंग ('?:') में रेगेक्स करना चाहते हैं: 'my_dict = dict (re.findall ...) ' – georg

+0

बहुत अच्छा सुधार। हालांकि: एक फ़ाइल ऑब्जेक्ट (और स्पष्ट रूप से 'रीडलाइन()' विधि को कॉल करने के बजाए, एक चर में सभी डेटा को पढ़ने), बहुत स्केलेबल नहीं है। 're.findall()' एक चर के बजाय एक पुनरावर्तक पर पूरी तरह से अच्छी तरह से काम करता है। – smci

4

अपने कोड के लिए कुछ quick'n'dirty अनुकूलन है:

my_dict = dict() 

with open(r'x:\path\to\file', 'r') as data: 
    for line in data: 
     match = re.search(pattern, line) 
     if match: 
      one_tuple = match.group(3, 2) 
      my_dict[one_tuple[0]] = one_tuple[1] 
+0

धन्यवाद, इससे – WiringHarness

1

मुझे यकीन है कि मैं द्वारा अनुशंसित नहीं कर रहा हूँ, लेकिन यहाँ एक तरह से आप के बजाय एक समझ का उपयोग करने की कोशिश कर सकते है (मैं प्रतिस्थापित एक सादगी के लिए फ़ाइल)

>>> import re 
>>> data = """1foo bar 
... 2bing baz 
... 3spam eggs 
... nomatch 
... """ 
>>> pattern = r"(.)(\w+)\s(\w+)" 
>>> {x[0]: x[1] for x in (m.group(3, 2) for m in (re.search(pattern, line) for line in data.splitlines()) if m)} 
{'baz': 'bing', 'eggs': 'spam', 'bar': 'foo'} 
+0

डिक्ट समझ में मदद मिली; मुझें यह पसंद है! – WiringHarness

2

EAFP की भावना में के लिए स्ट्रिंग मैं सुझाव देंगे

with open(r'x:\path\to\file', 'r') as data: 
    for line in data: 
     try: 
      m = re.search(pattern, line) 
      my_dict[m.group(2)] = m.group(3) 
     except AttributeError: 
      pass 

एक और तरीका सूचियों का उपयोग करना जारी रखना है, लेकिन पैटर्न को फिर से डिजाइन करना ताकि इसमें केवल दो समूह (key, value) शामिल हों। फिर आप बस कर सकते हैं:

matches = [re.findall(pattern, line) for line in data] 
    mydict = dict(x[0] for x in matches if x) 
+0

findall सहायक है। – WiringHarness

1
matchRes = pattern.match(line) 
if matchRes: 
    my_dict = matchRes.groupdict() 
+0

कृपया, कुछ विवरणों के साथ अपने कोड स्निपेट का पालन करें, पाठकों के लिए स्पष्टीकरण स्पष्ट करें। –