[RegEx] Logikfrage

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
paddy2706
User
Beiträge: 18
Registriert: Donnerstag 10. April 2008, 22:20

Samstag 22. November 2008, 17:36

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 8) mit einem regulären ausdruck zu ersetzen.

ich komm gerade leider nicht drauf, wie ich das anstellen kann :oops: , 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.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Samstag 22. November 2008, 17:49

Was ist das denn für eine Datei? XML oder CSV? Ist das auch valides XML? Der Tag

Code: Alles auswählen

<sty g>
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.
paddy2706
User
Beiträge: 18
Registriert: Donnerstag 10. April 2008, 22:20

Samstag 22. November 2008, 17:55

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ß
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Sonntag 23. November 2008, 10:01

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
paddy2706
User
Beiträge: 18
Registriert: Donnerstag 10. April 2008, 22:20

Mittwoch 26. November 2008, 16:25

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

Code: Alles auswählen

# -*- coding: utf-8 -*-
reingeschrieben habe.
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Mittwoch 26. November 2008, 17:32

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

Code: Alles auswählen

# -*- coding: utf-8 -*-
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
paddy2706
User
Beiträge: 18
Registriert: Donnerstag 10. April 2008, 22:20

Mittwoch 26. November 2008, 17:48

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.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Mittwoch 26. November 2008, 17:55

[wiki=Unicode]Unicode[/wiki] und [wiki=Von_Umlauten,_Unicode_und_Encodings]Von Umlauten, Unicode und Encodings[/wiki] gelesen?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Mittwoch 26. November 2008, 17:59

@paddy2706:
Den Bezeichner "file" solltest du besser ersetzen, weil "file" eine built-in-function ist.
paddy2706
User
Beiträge: 18
Registriert: Donnerstag 10. April 2008, 22:20

Mittwoch 26. November 2008, 18:26

hallo derdon und numerix, danke für eure hinweise.

ich habe jetzt ein

Code: Alles auswählen

datei.encode('utf-8')
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?!
BlackJack

Mittwoch 26. November 2008, 19:33

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.
paddy2706
User
Beiträge: 18
Registriert: Donnerstag 10. April 2008, 22:20

Mittwoch 26. November 2008, 20:57

danke für eure hilfe. das sub funktionen akzeptiert habe ich überlesen.
jetzt funktioniert soweit erstmal alles :)
Antworten