2013-02-14 11 views
5

मैं आपकी मदद पूछना चाहता हूं।पायथन: डेटा पकड़ने के लिए regex

मैं डेटा की एक बड़ी टुकड़ा है, जो इस तरह दिखता है:

 a 
    b : c 901 
    d : e sda 
v 
    w : x ads 
    any 
    abc : def 12132 
    ghi : jkl dasf 
    mno : pqr fas 
    stu : vwx utu 

विवरण: फ़ाइल एकल शब्द वाले एक लाइन के साथ शुरू होता है (यह सफेद स्थान के साथ शुरू कर सकते हैं और व्हाइटस्पेस शब्द के बाद भी हो सकता है), फिर कोलन द्वारा अलग किए गए गुणों की रेखा का अनुसरण करता है (व्हाइटस्पेस भी हो सकता है), फिर एक शब्द के साथ गुणों या रेखा की फिर से पंक्ति। मैं सही regex इस तरह के रूप में इसे पकड़ने के लिए नहीं बना सकते हैं:

{ 
    "a": [["b": "c 901"], ["d", "e sda"]], 
    "v": [["w", "x ads"]], 
    "any": ["abc", "def 12132"], ["ghi", "jkl dasf"], 
    # etc. 
} 

यहाँ मैं क्या कोशिश की है है:

regex = str() 
regex += "^(?:(?:\\s*)(.*?)(?:\\s*))$", 
regex += "(?:(?:^(?:\\s*)(.*?)(?:\\s*):(?:\\s*)(.*?)(?:\\s*))$)*$" 
pattern = re.compile(regex, re.S | re.M) 

हालांकि, यह मैं क्या जरूरत नहीं मिल रहा है। क्या तुम मेरी मदद कर सकते हो? मुझे पता है कि मैं लाइन-बाय-लाइन इटरेटर का उपयोग करके रेगेक्स के बिना फ़ाइल को संसाधित कर सकता हूं और ":" प्रतीक की जांच कर सकता हूं, लेकिन फ़ाइल इस तरह से संसाधित करने के लिए बहुत बड़ी है (यदि आप जानते हैं कि बिना किसी रेगेक्स के इसे कैसे संसाधित करना है, तो यह भी होगा सही जवाब, लेकिन सबसे पहले जो दिमाग में आता है वह बहुत धीमा है)।

अग्रिम धन्यवाद!

पीएस फ़ाइल के विहित प्रपत्र में इस तरह दिखता है:

a 
    b : c 901 
    d : e sda 

हर खंड एक शब्द के साथ शुरू होता है, तो गुण लाइन (दो व्हाइटस्पेस के बाद) का पालन करें, वहाँ विशेषताओं के साथ अलग होती है (":"), तो agane विशेषताओं लाइन या एक शब्द के साथ लाइन। अन्य सफेद जगह निषिद्ध हैं। शायद यह आसान हो जाएगा।

+0

+1 सुपर स्पष्टता; अच्छी तरह से तैयार सवाल। – Yavar

उत्तर

3

क्या नियमित अभिव्यक्तियां वास्तव में यहां आवश्यक हैं? इस छद्म कोड का प्रयास करें:

result = {} 

last = None 
for _line in data: 
    line = _line.strip().split(":") 
    if len(line) == 1: 
     last = line[ 0 ] 
     if last not in result: 
      result[ last ] = [] 
    elif len(line) == 2: 
     obj = [ line[ 0 ].strip(), line[ 1 ].strip() ] 
     result[ last ].append(obj) 

मुझे उम्मीद है कि मैं आपकी डेटा संरचना को सही ढंग से समझता हूं।

+2

यह सही दृष्टिकोण है, कोई रेगेक्स आवश्यक नहीं है, मेरे पास एक जवाब था, मैंने हटा दिया क्योंकि यह अनावश्यक नहीं है, यह वह समाधान है जिसकी आपको आवश्यकता है। (थोड़ा tweaking की आवश्यकता हो सकती है - लेकिन यह आप क्या चाहते हैं) +1 –

0

आप इस regex का उपयोग कर सकते हैं ..

(?:[\n\r]+|^)\s*(\w+)\s*[\n\r]+(\s*\w+\s*:\s*.*?)(?=[\n\r]+\s*\w+\s*[\n\r]+|$) 

आप मैचsingleline साथ ऊपर regex या dotall विकल्प की जरूरत है

GROUP1 और GROUP2 क्या आप हर बार चाहते हैं आप

से मेल से मेल खाता है

here ..यूज़ डॉट सभी विकल्प

0
# a more golf - like solution 
from itertools import groupby 

groups = groupby(map(lambda s: map(str.strip,s.split(':')), data), len) 
dict((next(i[1])[0], list(next(groups)[1])) for i in groups) 

आउट:

{'a': [['b', 'c 901'], ['d', 'e sda']], 
'any': [['abc', 'def 12132'], 
    ['ghi', 'jkl dasf'], 
    ['mno', 'pqr fas'], 
    ['stu', 'vwx utu']], 
'v': [['w', 'x ads']]}