2013-02-14 17 views
5

Ich möchte Ihre Hilfe fragen.Python: Regex, um Daten zu fangen

Ich habe ein großes Stück von Daten, die wie folgt aussieht:

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

Beschreibung: Datei mit einer Zeile beginnt enthält einzelnes Wort (es kann mit Leerzeichen beginnen und Leerzeichen können auch nach dem Wort sein), folgt dann Zeile von Attributen getrennt durch Doppelpunkt (kann auch Leerzeichen haben), dann wieder Zeile von Attributen oder Zeile mit einem einzelnen Wort. Ich kann nicht die richtige regex schaffen es in einer solchen Form zu fangen:

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

Hier ist, was ich versucht habe:

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

es jedoch nicht finden, was ich brauche. Kannst du mir helfen? Ich weiß, dass ich Datei ohne Regex verarbeiten könnte, mit Zeile-für-Zeile-Iterator und nach ":" Symbol suchen, aber Datei ist zu groß, um es auf diese Weise zu verarbeiten (wenn Sie es schnell ohne Regex verarbeiten können, wird dies auch sein) richtige Antwort, aber zuerst ist das zu langsam).

Vielen Dank im Voraus!

P.S. In der kanonischen Form der Datei wie folgt aussieht:

a 
    b : c 901 
    d : e sda 

Jeder Abschnitt mit einem einzigen Wort beginnt, dann Attribute Linie folgen (nach zwei Leerzeichen), werden dort Attribute getrennt mit („:“), dann Agane Attribute Linie oder Zeile mit einem einzelnen Wort. Andere Leerzeichen sind verboten. Wahrscheinlich wird es einfacher sein.

+0

+1 Super-Clarity; Ordentlich gerahmte Frage. – Yavar

Antwort

3

Sind hier reguläre Ausdrücke wirklich notwendig? Versuchen Sie diesen Pseudocode:

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) 

Ich hoffe, ich verstehe Ihre Datenstruktur richtig.

+2

Dies ist der richtige Ansatz, keine Regex benötigt, ich hatte eine Antwort hier gelöscht ich, weil es nicht unnötig ist, das ist die Lösung, die Sie brauchen. (Vielleicht brauchen Sie ein wenig Feinschliff - aber was Sie wollen) +1 –

0

Sie diese Regex verwenden können ..

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

Sie müssen Spiel die oben regex mit singleline oder dotall Option

Gruppe1 und Gruppe2 übereinstimmt, was Sie jedes Mal, wenn Sie

entsprechen

check out here ..use dot alle option

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) 

aus:

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