Reguläre Ausdrücke

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
christine
User
Beiträge: 31
Registriert: Dienstag 24. Februar 2009, 10:03

Hi zusammen,

ich bin ein regDau :oops:

Wie kann man eine Zeile folgender Regel in einen regulären Ausdruck verpacken:

Text (evtl. mit Leerzeichen);x;;1205733[irgendeine Zahl]

Hier ein Ausschnitt aus meiner CSV Datei:

Essen Allgemein;x;;1205733
Mittagessen;x;;519900
Guten Appetit;x;;519930
Hunger;x;x;519937
Durst;x;;630419

Hier meine Idee (die ja leider nicht funktioniert):
ausdruck = r"([\W\s]+)(;x;;)(\d{2,})"


Ich möchte dann den Text und die Zahl in eine Datei schreiben (bzw damit eine xml Datei füttern):
<Text>Text</Text><Verwendung ID=Zahl/>
<Text>Essen Allgemein</Text><Verwendung ID=1205733/>

also über group(0) und (2) auf die Teilstrings zugreifen....


Kann mir jemand beim regulären Ausdruck helfen?

lg, Christine
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wieso benutzt Du nicht einfach das ``csv``-Modul?

Code: Alles auswählen

>>> data = """
... Essen Allgemein;x;;1205733
... Mittagessen;x;;519900
... Guten Appetit;x;;519930
... Hunger;x;x;519937
... Durst;x;;630419
... """

>>> import csv

>>> for row in csv.reader(data.split("\n"), delimiter=";"):
...     print(row)
[]
['Essen Allgemein', 'x', '', '1205733']
['Mittagessen', 'x', '', '519900']
['Guten Appetit', 'x', '', '519930']
['Hunger', 'x', 'x', '519937']
['Durst', 'x', '', '630419']
[]
Du kannst jetzt ganz einfach per Index auf eine Spalte zugreifen, also hier ``0`` und ``3``.

Das XML kannst Du dann einfach per ElementTree-API erstellen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
christine
User
Beiträge: 31
Registriert: Dienstag 24. Februar 2009, 10:03

Hi Hyperion,

danke für den Hinweis!

Ich werde es mal damit versuchen. Mal schauen ob ich es hin bekomme. Dein Lösungsvorschlag ist nathürlich schicker...
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Das \W steht für alles, was kein Wort ist, wobei Wort a-z, A-Z und 0-9 bedeutet (und noch ein paar andere Buchstaben im Unicode-Modus). Besser ist es IMHO, einfach alles bis auf ; zu nehmen, also [^;]*. Die erste Match-Gruppe ist übrigens 1, nicht 0. Mit 0 erhält man den kompletten Match. Und das, was man nicht haben will, muss man auch nicht gruppieren, oder aber man kann der offenen Klammer ein ?: folgen lassen.

In meinem Beispiel nutze ich noch einen anderen Trick: ^ steht dank (?m) für den Anfang jeder Zeile und $ für das Ende. Damit kann ich zusammen mit findall() gleich eine Schleife über alle möglichen Ergebnisse finden. Ohne (?m) würde ^ für den Anfang des Strings und $ für dessen Ende stehen. Statt (?m) könnte ich auch re.M als weiteres Argument bei findall() angeben, doch ich finde es so schöner.

Code: Alles auswählen

import re

s = """Essen Allgemein;x;;1205733
Mittagessen;x;;519900
Guten Appetit;x;;519930
Hunger;x;x;519937
Durst;x;;630419"""

for text, zahl in re.findall(r"(?m)^([^;]+);x;;(\d+)$", s):
    print text, zahl
Stefan
christine
User
Beiträge: 31
Registriert: Dienstag 24. Februar 2009, 10:03

Hallo sma,

vielen Dank auch für deine Antwort. Ich habe es gerade mal versucht, super! Vielleicht schnall ich diese regulären Ausdrücke ja irgend wann auch mal :-)

Ich scripte halt nicht so oft, immer wenn ich was brauche muss ich mich neu einlesen *nerv*


Grüße,
christine
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@christine: Nichts gegen sma, den RegExp-Gott, aber hältst Du die Lösung per RegExps wirklich übersichtlicher? Kannst Du den RegExp auf die Schnelle so abändern, dass er Semikola in Zeichenketten `"` akzeptiert? Natürlich geht man nicht von solch einer möglichen Formatänderung aus, aber oftmals gibt es ja keine Garantie für das Format einer CSV - da ist mir das `csv`-Modul angenehmer...

Ok, in der Version 2.x ist es ordentlich "verbuggt", da die UTF-8 Unterstützung eher mau ist und nur mittels Workaround funktioniert. Da dieser aber aus der Doku eins zu eins übernommen werden kann, kommt man damit auch zurecht, wenn man es denn weiß.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
christine
User
Beiträge: 31
Registriert: Dienstag 24. Februar 2009, 10:03

Hi Hyperion,

ich finde die Version mit dem Element-tree eleganter, eben weil einfacher anpassbar. Trotzdem finde ich die Lösung von sma auch super und für mich ist jeder Ansatz hilfreich. Vor dem Unicodeproblem stehe ich gerade ;-) Habe aber deine Sig entdeckt und lese mich mal schlau. Wie schreibt man den "leere" Tags mit dem Element-Tree? Das konnte ich noch nicht finden. Also
<TAGNAME ID"hierWerteinfüllen" />

Lg chirstine
BlackJack

@christine: Man erstellt für ein Element einfach keine Kindelemente. Also da gibt es nichts spezielles was man machen muss.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

christine hat geschrieben: ich finde die Version mit dem Element-tree eleganter, eben weil einfacher anpassbar.
Du meinst mit dem `csv`-Modul? Die `ElementTree`-API habe ich ja nur als Tipp für die XML-Generierung gegeben ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
christine
User
Beiträge: 31
Registriert: Dienstag 24. Februar 2009, 10:03

ach, mist, jetzt schmeiss ich glaub alles durcheinander ;-)
sorry, bin grad ein bissle in hektik....
christine
User
Beiträge: 31
Registriert: Dienstag 24. Februar 2009, 10:03

also, was ich sagen wollte, es ist schicker mit DOM ein File zu bauen, als String basiert... Aber das könnt ich ja auch über DOM bauen, wenn ich mit regulären Ausdrücken suche, ja, du hast recht
Antworten