2017-12-23 12 views
1

Hier ist meine Zeichenfolge, die ich durch Analysieren von Daten aus einer Datei erstellt:Python-String Transformation

723|NM|1|7201|QQ|1|72034|PP|1|72034N|AA|1|7203466|QW|1|72000|NM|1|7201111|NM|1 

Idealerweise würde ich diesen Ausgang mag:

723|NM|1 
7201|QQ|1 
72034|PP|1 
72034N|AA|1 
7203466|QW|1 
72000|NM|1 
7201111|NM|1 

Da ich nicht erfolgreich war Analysieren der Daten und es dynamisch anhängen (ich bin neu bei Python) Ich verstehe, dass ich die gleiche gewünschte Ausgabe durch Umwandlung dieser Zeichenfolge erhalten kann.

Ich recherchierte, getestet und bin fest.

Im Wesentlichen muss ich jede dritte Instanz des Trennzeichens durch eine neue Zeile ersetzen (oder vielleicht etwas Besseres, das jemand vorschlagen kann).

Jede Hilfe wird sehr geschätzt!

Dank

+0

Können Sie uns ein Beispiel dafür geben, wie die Eingabedatei aussieht? – TheF1rstPancake

+0

Sicher, es war eine XML-Datei und ich analysierte ein verschachteltes Segment. Nativ erkannte Python nicht, dass jedes verschachtelte Segment unabhängig war, also analysierte ich es einfach in eine Zeichenkette, in der ich wusste, dass jedes dritte Stück am Ende aufgeteilt werden konnte, wodurch effektiv eine Datei erstellt wurde, die ich in eine Tabelle laden konnte. – Scientific40

Antwort

5

ohne regex:

wie folgt:

s = "723|NM|1|7201|QQ|1|72034|PP|1|72034N|AA|1|7203466|QW|1|72000|NM|1|7201111|NM|1" 

items = s.split("|") 
print("\n".join(["|".join(items[i:i+3]) for i in range(0,len(items),3)])) 

zur Kenntnis, dass die [] innerhalb des äußeren join absichtlich ist, eine bessere Leistung (List comprehension without [ ] in Python) zu bekommen (auch wenn ich damit einverstanden, dass es hässlich :) ist)

Ergebnis:

723|NM|1 
7201|QQ|1 
72034|PP|1 
72034N|AA|1 
7203466|QW|1 
72000|NM|1 
7201111|NM|1 

BTW mit regex es ist einfach zu:

re.sub("(.*?\|.*?\|.*?)\|","\\1\n",s) 

aber es sehr gut funktioniert nicht, wenn die Anzahl der Elemente von 3 nicht genau teilbaren sind (thi s kann getan werden, aber in einer komplexeren Art und Weise)

+0

Ja schön, Sie haben eine extra [] in Ihrer print-Anweisung, die nicht benötigt wird (Outer Join). Und du könntest es auch so schreiben: 'print ('\ n'.join (' | '.join (i) für i in zip (Gegenstände [:: 3], Gegenstände [1 :: 3], Gegenstände [2 :: 3]))) ' –

+2

die' [] 'ist absichtlich, für eine bessere Leistung: https://stackoverflow.com/questions/9060653/list-comprehension-without-in-python –

+0

Dies funktionierte perfekt ... Ich glaube, ich war nah dran, und jetzt sollte ich Dinge zum Laufen bringen. Vielen Dank! – Scientific40

0

eine Regex-Lösung:

import re 

string = """723|NM|1|7201|QQ|1|72034|PP|1|72034N|AA|1|7203466|QW|1|72000|NM|1|7201111|NM|1 
723|NM|1|7201|QQ|1|72034|PP|1|72034N|AA|1|7203466|QW|1|72000|NM|1|7201111|NM|1|123|NM""" 

rx = re.compile(r'(?:[^|]+\|?){1,3}') 

for line in string.split("\n"): 
    parts = "\n".join([part.group(0).rstrip("|") for part in rx.finditer(line)]) 
    print(parts) 

Dies ergibt:

723|NM|1 
7201|QQ|1 
72034|PP|1 
72034N|AA|1 
7203466|QW|1 
72000|NM|1 
7201111|NM|1 
723|NM|1 
7201|QQ|1 
72034|PP|1 
72034N|AA|1 
7203466|QW|1 
72000|NM|1 
7201111|NM|1 
123|NM 

Siehe a demo on regex101.com.

+0

Dies löscht die letzte Zeile, wenn die Anzahl der Elemente kein Vielfaches von 3 ist. –

+0

@ Jean-FrançoisFabre: Der Ausdruck sowie die Demo wurden aktualisiert (beachten Sie, dass die zweite Zeile nicht durch drei teilbar ist). – Jan

+0

hmmm, das regex verwendet und es anschließend mit einer Menge Strings repariert. Das bedeutet, dass Ihre Regex101-Demo nicht mehr BTW hält. Ich bin mir sicher, dass es mit einer intelligenten Regex und keine Nachbearbeitung getan werden kann, aber ich bin zu faul, es zu versuchen. –

0

Sie reguläre Ausdrücke verwenden können, und dieses Muster ausprobieren können:

import re 

pattern=r'\d+\w\|\w+\|\d' 
with open('file.txt','r') as f: 
    for line in f: 
     match=re.findall(pattern,line) 
     for i in match: 
      print(i) 

Ausgang:

723|NM|1 
7201|QQ|1 
72034|PP|1 
72034N|AA|1 
7203466|QW|1 
72000|NM|1 
7201111|NM|1 

Just for fun in einer Zeile:

import re 

pattern=r'\d+\w\|\w+\|\d' 
for i in [re.findall(pattern,line) for line in open('file.txt','r')][0]: 
    print(i) 

Ausgabe:

723|NM|1 
7201|QQ|1 
72034|PP|1 
72034N|AA|1 
7203466|QW|1 
72000|NM|1 
7201111|NM|1