Seite 1 von 1
[RegEx] Logikfrage
Verfasst: Samstag 22. November 2008, 17:36
von paddy2706
Hallo ihr lieben,
ich hab mal wieder eine Frage der Logik.
Ich muss eine Datei (CSV mit XML-ähnlichen-Feldern) mit einem solchen Inhalt (1. Eintrag):
Code: Alles auswählen
"ï áíèñùðïò
<ent>
<wrd>
<lin><sty g>o`` a;nqrwpoj<med><aud>00\Gr-0004-01.wav</aud></med></lin>
</wrd>
<phr>
<lin><sep><par></sep><sty g>ku,rioj ga,r evstin tou/ sabba,tou o` ui`o.j tou/ <gap>avnqrw,pou</gap>Å</lin>
</phr>
</ent>","Mensch
<ent>
<wrd>
<lin>Mensch</lin>
</wrd>
<phr>
<lin><sep><par></sep>Denn der Sohn des <gap>Menschen</gap> ist Herr des Sabbats. <sty b>(Mt 12,8)</lin>
</phr>
</ent>",0,65,"11/17/05 00:00:00",4,"L05",1,16,1,""
den teil der jeweils zwischen <sty g> und dem nächsten beliebigen tag steht (Z4 und

mit einem regulären ausdruck zu ersetzen.
ich komm gerade leider nicht drauf, wie ich das anstellen kann

, denn wenn ich vorher einfach mit re.search nach <sty g>(...)<*> suche dann modifiziere ich ja nur den array und nicht den text in der datei
würde mich freun, wenn jemand von euch ne idee hat.
Verfasst: Samstag 22. November 2008, 17:49
von derdon
Was ist das denn für eine Datei? XML oder CSV? Ist das auch valides XML? Der Tag
wird zwei mal geöffnet, aber nicht ein mal geschlossen. Wenn das eine XML-Datei ist, dann sollte sie auch mit einem entsprechenden Modul (z.B. ElementTree) geparst werden. Was bedeutet die erste Zeile in deiner Datei? Vielleicht solltest du dir mal den [wiki=Von_Umlauten,_Unicode_und_Encodings]Abschnitt zu Unicode und Encodings[/wiki] angucken.
Verfasst: Samstag 22. November 2008, 17:55
von paddy2706
hallo don,
leider habe ich mir das dateiformat nicht ausgedacht, es ist die datenbank von dem Langenscheidt Vokabeltrainer. Da dieser nicht ge-wine'd läuft, möchte ich die Datenbank zu parley bzw. kvtml2 konvertieren. Die erste Zeile und die <sty g> sind beides die selben Daten in zwei verschiedenen Formaten, deren Konvertierungslogik ich bereits geschrieben habe (ist übrigens Griechisch in diesem Fall).
Die Datei ist wie ich geschrieben habe ein CSV, in dem einzelne Felder (immer das erste und das zweite Feld), einen XML-ähnlichen Inhalt haben. Das ich hier kein ET anwenden kann, habe ich mir schon gedacht, damit wäre die sache ja recht einfach....
Gruß
Verfasst: Sonntag 23. November 2008, 10:01
von sma
Datei laden, ersetzen, Datei speichern. Das deine <sty g>-Marken in einer CSV-artigen Datei stecken, spielt doch in deinem Fall keine Rolle.
Code: Alles auswählen
s = open("...").read()
s = re.sub(r'(?s)(?<=<sty g>)(.*?)(?=<\w+>)', r'XXXX', s)
open("...", "w").write(s)
Stefan
Verfasst: Mittwoch 26. November 2008, 16:25
von paddy2706
ich hab echt ein schlechtes gewissen so dumme fragen zu stellen:
ich versuche jetzt das ganze gegen 3 dicts zu ersetzen:
hier ein ausschnitt aus einem der drei:
Code: Alles auswählen
dict1={"A":unichr(913),"B":unichr(914),"G":unichr(915),"D":unichr(916)}
dazu hatte ich im internet diese funktion gefunden, mir ist im moment leider nicht klar, wie ich das zusammenbauen kann - aus dem
python regex howto werde ich leider auch nicht schlau.
Code: Alles auswählen
def replace_all(text, dic):
for i, j in dic.iteritems():
text = text.replace(i, j)
return text
file = replace_all(file, dict1)
von der logik her denke ich muss ich mit re.search die einzelnen matches der o.g. regex suchen und sie dann mit meinem dict ersetzen, so dass alle daten in dem string bleiben. wie kann ich das machen?
noch ein anderes problem macht mir das encoding. wenn ich den o.g. funktion replace_all über einen beliebigen text jage, meldet er mir etwas wie
Code: Alles auswählen
UnicodeEncodeError: 'ascii' codec can't encode character u'\u0391' in position 0: ordinal not in range(128)
, obwohl ich oben in den code schon
reingeschrieben habe.
Verfasst: Mittwoch 26. November 2008, 17:32
von helduel
Moin,
paddy2706 hat geschrieben:von der logik her denke ich muss ich mit re.search die einzelnen matches der o.g. regex suchen und sie dann mit meinem dict ersetzen, so dass alle daten in dem string bleiben. wie kann ich das machen?
wenn ich dich richtig verstanden habe, dann dürfte re.sub deinen Bedürfnissen entsprechen. Dieser Funktion kannst du eine eigene Funktion übergeben, die bei jedem Match aufgerufen wird und deren Rückgabe in den Text einsetzt.
noch ein anderes problem macht mir das encoding. wenn ich den o.g. funktion replace_all über einen beliebigen text jage, meldet er mir etwas wie
Code: Alles auswählen
UnicodeEncodeError: 'ascii' codec can't encode character u'\u0391' in position 0: ordinal not in range(128)
, obwohl ich oben in den code schon
reingeschrieben habe.
Das coding:...-Zeugs sagt nur aus, mit welchem Encoding dein Python-Skript geschrieben wurde. Das hat nichts mit dem Encoding der Daten, die du verarbeitest, zu tun. Wo genau tritt dieser Fehler denn auf?
Gruß,
Manuel
Verfasst: Mittwoch 26. November 2008, 17:48
von paddy2706
Hallo Manuel,
Das coding:...-Zeugs sagt nur aus, mit welchem Encoding dein Python-Skript geschrieben wurde. Das hat nichts mit dem Encoding der Daten, die du verarbeitest, zu tun. Wo genau tritt dieser Fehler denn auf?
der Fehler tritt bei dieses Beispielskript in der letzten zeile auf. (die funktion replace_all siehe letzter Post von mir). selbes problem tritt auch bei open('test','w').write(file) auf.
Code: Alles auswählen
file = "A"
dict1={"A":unichr(913),"B":unichr(914),"G":unichr(915),"D":unichr(916)}
file = replace_all(file,dict1)
print file
danke soweit
EDIT: mit print tritt der fehler nur in Stanis Python Editor auf, wenn ichs direkt in nem terminal ausführe ist es kein problem. aber mit dem schreiben in die datei funktioniert auch aufm terminal nicht.
Verfasst: Mittwoch 26. November 2008, 17:55
von derdon
[wiki=Unicode]Unicode[/wiki] und [wiki=Von_Umlauten,_Unicode_und_Encodings]Von Umlauten, Unicode und Encodings[/wiki] gelesen?
Verfasst: Mittwoch 26. November 2008, 17:59
von numerix
@paddy2706:
Den Bezeichner "file" solltest du besser ersetzen, weil "file" eine built-in-function ist.
Verfasst: Mittwoch 26. November 2008, 18:26
von paddy2706
hallo derdon und numerix, danke für eure hinweise.
ich habe jetzt ein
direkt nach dem auslesen eingebaut.
jetzt bekomme ich diese interessante fehlermeldung:
Code: Alles auswählen
datei.encode('utf-8')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 111: ordinal not in range(128)
die datei fängt mit der folgenden zeile an:
Code: Alles auswählen
Griechisch,Deutsch,Filter,Sort,Edited,Nr,StoyHaagHaubeck,Rehkopf_Nr,Nr_In_Lektion,Wortart_Nr,Wortartkategorie
"ï áíèñùðïò
Pos 111 ist nach meiner Rechnung die neue Zeile.
Da die Ursprungsdatei eigentlich schon UTF-8 ist, verwundert mich, dass es hier ein problem gibt. kann das normale open kein uft-8 und muss ich hier schon codecs.open benutzen?!
Verfasst: Mittwoch 26. November 2008, 19:33
von BlackJack
Das normale `open()` kennt keine Kodierungen, dass kennt nur Bytes.
Dein Problem ist, dass Du Bytes liest und die *en*kodieren willst, wo Du sie eigentlich *de*kodieren müsstest. Du willst ja aus Bytes ein `unicode`-Objekt erzeugen. Was bei `str.encode()` passiert: Da ``encode('utf-8')`` hier nur auf `unicode` Sinn macht, versucht Python das `str`-Objekt vorher zu dekodieren. Weil dafür keine explizite Kodierung angegeben wurde, wird 'ascii' angenommen. Und das knallt natürlich wenn da Bytewerte ausserhalb von ASCII vorkommen.
Verfasst: Mittwoch 26. November 2008, 20:57
von paddy2706
danke für eure hilfe. das sub funktionen akzeptiert habe ich überlesen.
jetzt funktioniert soweit erstmal alles
