Seite 1 von 1
String parsen (value)
Verfasst: Dienstag 30. Juli 2019, 11:03
von Kirikkayis
Hey Leute,
ich hab eine Serielle Schnittstelle von der ich Daten erhalte.
Diese sehen wie folgt aus:
's6H\x1b(s0B\x1b(s12H\x1b(s0B\r\n','Operator:30.07.1911:04\r\n','\r\n','RotordatenFall1\r\n','\r\n','a:40.00mmb:82.00mmc:40.00mm\r\n','\r\n','r1:22.00mmStatr2:49.00mm\r\n','\r\n','m1:-polar\x00m2:-polar\x00\r\n','\r\n','Tol1:2.000gmmTol2:1.000gmm\r\n','\r\n','Maschine:2Nsoll:729.1/Min\r\n','\r\n','ErgebnisseRotor:30.07.1911:04\r\n','\r\n','Lauf1Nist:729.1/Min\r\n','\r\n','Stat743.mg\r\n','\r\n','298.Grad\r\n','\r\n','8.2*Tol\r\n','\r\n','AnteilinTol.Einheiten:\r\n','16.35gmm\r\n',''
Nun brauche hier einzelne "values".
Beispiel:
Ich benötige beispielsweise die folgenden Werte: 'a', 'Nsoll' und 'Rotor' uvm.
Als Antwort reicht mir wirklich nur die einzelnen "values" also 40.00 ; 729.1 und 30.07.19 11:04
Erst dachte ich an das "String-Splitting", da ich aber bei den meisten werten keinen "trenner" wie beispielsweise ein komma oder ein Semikolon habe, bin ich mir nicht mehr ganz so sicher ob das funktioniert. (Siehe beispiel 'a:40.00mmb:82.00mmc:40.00mm\r ...'
Jemand eine Idee?
Re: String parsen (value)
Verfasst: Dienstag 30. Juli 2019, 11:21
von __blackjack__
Reguläre Ausdrücke‽
Re: String parsen (value)
Verfasst: Dienstag 30. Juli 2019, 11:28
von Kirikkayis
Daran arbeite ich gerade, jedoch ist das extrem hässlich und umständlich.
Es funktioniert, ist aber nicht state of the art
Ich lasse mich sehr gerne eines besseren belehren, falls ich Optimierungsvorschläge etc. habt bzw. n komplett anderes Vorgehen dann nur raus damit

Nun ich gehe wie folgt vor:
Code: Alles auswählen
#block 1
regex = r"[a]:\d+.\d+"
matches = re.finditer(regex, data, re.MULTILINE)
for matchNum, match in enumerate(matches, start=1):
print(match.group())
hallo = match.group()
#block2
regex1 = r"\d+.\d+"
matches = re.finditer(regex1, hallo, re.MULTILINE)
for matchNum, match in enumerate(matches, start=1):
print(match.group())
Ich habe mal die einzelnen "Blöcke" kommentiert, damit ich es besser erläutern kann.
Block1:
Ich erhalte einen String (data) diesen parse ich nach "a: zahl . zahl "
Da ich aber einen float brauche, muss ich das erhaltene Ergebnis erneut parsen.
Somit kommen wir zu Block 2 ...
Block2:
Ich hab ich Block1 eine Variable (hallo) hier steht das Ergebnis "a: zahl . zahl"
Dies wird erneut geparst weil ich nur einen float haben möchte.
Ich denke es ist extrem Aufwändig, zumindest so wie ich es jetzt mache.

Re: String parsen (value)
Verfasst: Dienstag 30. Juli 2019, 11:38
von __blackjack__
@Kirikkayis: Da Du eine Liste mit Zeichenketten hast, macht das MULTILINE keinen Sinn. `hallo` ist ein unsinniger, schlechter Name. Und da Du `group()` bereits kennst: Gruppiere halt gleich im ersten Ausdruck das was Du extrahieren möchtest und frag dann die Gruppe ab. Ich würde auch mehr von dem was da tatsächlich im Text steht in den Ausdruck packen, denn 'a:irgendeine Zahl' könnte auch irgendwo anders mittendrin vorkommen. Das 'a' steht am Anfang und nach der Zahl folgt noch ein 'mm'.
Code: Alles auswählen
regex = re.compile(r'^a:(\d+.\d+)mm')
for line in lines:
match = regex.search(line)
if match:
print(float(match.group(1)))
Wenn man da mehrere Alternativen in den regulären Ausdruck steckt, dann sollte man benannte Gruppen verwenden, sonst kommt man mit den Nummern schnell mal durcheinander.
Re: String parsen (value)
Verfasst: Dienstag 30. Juli 2019, 12:16
von sparrow
Ungetestet:
Edit: \w bei den mm vergessen
Re: String parsen (value)
Verfasst: Dienstag 30. Juli 2019, 12:36
von Kirikkayis
Danke __Blackjack__ für deine Vorschläge.
Den Variablennamen habe ich erst mal random gesetzt gehabt (zum testen).
Bzgl. MULTILINE hast du recht, da habe ich mich in der Doku um eine Zeile verlesen
Bezüglich deiner Anmerkung, das "a" öferts vorkommen könnte.
Ein solches Problem habe ich nicht, die Datei ist Statisch.
@sparrow, kannst du mir deine Zeile Code Erläutern bitte?
Es ist ein regex für das Beispiel um "a" zu parsen, wenn ich es richtig herausgelesen habe ?
Oder Irre ich mich?
Danke.
Re: String parsen (value)
Verfasst: Dienstag 30. Juli 2019, 12:37
von sparrow
Mit dem Regex solltest du alle Key-Value-Paare ohne Anhängsel an die Werte (sprich Einheiten) bekommen. Ich dachte, das wolltest du?
Re: String parsen (value)
Verfasst: Dienstag 30. Juli 2019, 12:41
von Kirikkayis
Mit deiner Lösung kann ich "a" , "b" und "c" problemlos parsen.
Wie sieht es mit Rotor als bspl aus?
Oder mit 'AnteilinTol.Einheiten: ...'
Re: String parsen (value)
Verfasst: Dienstag 30. Juli 2019, 12:45
von sparrow
Wie wäre es, wenn du es einfach ausprobierst?
Und hier eine Variante, die auch nicht die Minuten vergisst:
Code: Alles auswählen
r"(\w*mm)*(?P<key>[.\w]+):(?P<value>\d+[.\d]*(:\d\d)?)*"
Re: String parsen (value)
Verfasst: Dienstag 30. Juli 2019, 13:29
von __blackjack__
@Kirikkayis: Das 'a:' nicht öfters vorkommen ist eine Annahme die man nicht so pauschal treffen sollte wenn man sich *einfach* gegen so einen Fall absichern kann. Irgendwann ändert sich dann doch mal was und es muss ja nicht nur ein einzelnes 'a' sein – sondern Deine Suche hätte ja auch alles als 'a:' gefunden das mit einem a vor dem Doppelpunkt aufhört, also 'extrema:' beispielsweise hättest Du ja auch als 'a:' gefunden.