Aktuelle Zeit: 15.11.2019 16:01

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Fehler mit regulärem Ausdruck
BeitragVerfasst: 09.10.2019 05:30 
Offline

Registriert: 13.05.2017 01:44
ich erschließe für mich gerade die Anwendung regulärer Ausdrücke und bin auf ein Programmverhalten gestoßen, das ich mir nicht erklären kann. Folgender Kode, bei dem im String zdZk alle vorkommenden "dass" durch "daß" ersetzt werden sollen (also eine Art Neue-in-alte-Rechtschreibung-Umwandler) funktioniert einwandfrei:
Code:
Define.s zdZk ; zu durchsuchende Zeichenkette
zdZk="Da lagen einige junge Schwalben zerschmettert am Boden. Erstaunt "+
"untersuchte ich die Sache und fand heraus, dass die Schwalben selbst ihre "+
"Jungen aus den Nestern geworfen hatten!"

CreateRegularExpression(0, "dass\b")
zdZk=ReplaceRegularExpression(0, zdZk, "daß")
FreeRegularExpression(0)
Debug zdZk
Das "dass" in der zweiten Zeile wird wie gewünscht durch "daß" ersetzt.

Nun ist die eigentliche Anwendung natürlich um einiges komplexer: Ich habe eine Datei erstellt, bei der in jeder Zeile Suchausdruck und Ersetzungstext nebeneinander stehen und manche Zeilen wie oben den regulären Ausdurck \b (Wortgrenze) enthalten; später sollen ausgefeiltere reguläre Ausdrücke dazukommen dürfen. Sie sieht etwa so aus:
Zitat:
dass\b daß
Essst Eßst
ewusst ewußt
isschen ißchen
lässt\b läßt
lussst lußst
Missst Mißst
musst mußt
usw.
Die Idee ist dabei, diese Datei mit Such- und Ersetzungsausdrücken auf Textdateien in neuer Rechtschreibung anzuwenden und sie in die alte Rechtschreibung zurückzuüberführen. Da die umzuwandelnden Dateien z.T. sehr groß sind, wird deren Inhalt zuerst in den Arbeitsspeicher und vor dort in einen String geschrieben (dieser Teil des Kodes funktioniert). Dieser String wird dann durchsucht und alle vorkommenden Wörter in alter Rechtschreibung ersetzt. Im folgenden Beispiel ist der Inhalt der Datei zuD identisch mit dem des Strings zdZk von oben:
Code:
#Ed="D:\Ersetzung neue Rechtschreibung Wortliste.txt"
Define KrA  ; Kennzeichner regulärer Ausdruck
Define.s zuD, ZmrA, rA, Wed ; zu überprüfende Datei, (Zeile mit) regulärem Ausdruck, Wort ersetzen durch

zuD="D:\umzuwandelnder Text.txt"
ReadFile(0, #Ed, #PB_Unicode) ; Datei mit Suchmustern öffnen
If ReadFile(1, zuD, #PB_Unicode)  ; Öffnen der Datei erfolgreich
  ReadStringFormat(1) ; setzt den Dateizeiger an das Ende der BOM
  Define *P, Dl, Di.s ; Puffer, Dateilänge, Dateiinhalt
  Dl=Lof(1)
  *P=AllocateMemory(Dl, #PB_Memory_NoClear) ;   
  If *P
    ReadData(1, *P, Dl) ; Datei ab Adresse *P in den Puffer schreiben
    Di=PeekS(*P)    ; liest den kompletten Puffer aus und schreibt
    FreeMemory(*P)  ; ihn in die Zeichenkette Di
  EndIf
  CloseFile(1)
EndIf

While Not Eof(0)
  ZmrA=ReadString(0) ; Zeile mit regulärem Ausdruck einlesen
  rA=StringField(ZmrA, 1, " ")  ; regulären Ausdruck extrahieren
  Wed=StringField(ZmrA, 2, " ") ; Ersetzungsausdruck extrahieren
  KrA=CreateRegularExpression(#PB_Any, rA)
  Di=ReplaceRegularExpression(KrA, Di, Wed)
  Debug Di
  FreeRegularExpression(KrA)
Wend
CloseFile(0)  ; Datei mit Suchmustern schließen

If CreateFile(2, zuD, #PB_Unicode) ; Pfad zur Zieldatei
  WriteStringFormat(2, #PB_Unicode)
  WriteString(2, Di): CloseFile(2)
EndIf

Bis zur Zeile
Code:
KrA=CreateRegularExpression(#PB_Any, rA)
in der While-Wend-Schleife funktioniert alles perfekt. Aber die Ersetzung von "dass" in "daß" in der Zeile darauf findet nicht statt, d.h. der String Di bleibt unverändert. Obwohl die eingelesene Datei zuD den gleichen Inhalt hat wie oben der String zdZk, findet in ihr nicht die gewünschte Ersetzung statt. Wieso?

_________________
Windows 7 x64; geposteter Kode bezieht sich (sofern nicht anders angegeben) immer auf das aktuellste PureBasic 64-Bit

Erst wenn man es seiner Schwiegermutter erklären kann, hat man es verstanden.
As gsündeste is oiwei guad essn und dringa und ned grang wern.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Fehler mit regulärem Ausdruck
BeitragVerfasst: 09.10.2019 10:36 
Offline
Kommando SG1
Benutzeravatar

Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Da ich den zweiten Code nicht ausführen kann, kann ich nur vermuten, dass es auch in der Suchmusterdatei (File 0) einen BOM gibt. Diesen ließt du aber nicht aus (wie du es bei File 1 machst). Somit ließt du die erste Zeite des Suchmusters mit dem BOM ein, was du dann später natürlich nicht finden kannst.

_________________
Bild
 
BildBildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Fehler mit regulärem Ausdruck
BeitragVerfasst: 09.10.2019 11:25 
Offline
Benutzeravatar

Registriert: 20.04.2006 09:50
- Wie Stargate bereits sagte würdest du den BOM mit im String haben.
- Bist du sicher das du die Dateien als UTF-16 (#PB_Unicode) lesen willst? Normalerweise würdest du den BOM auslesen und dann als Format-Flag weiterreichen.
- Du kannst ReadString() mit #PB_File_IgnoreEOL verwenden um alle Zeilen in einen String zu lesen.
- Eventuell willst du den BOM aus der Quelldatei wieder in die Ausgabedatei schreiben (wird im folgenden Code nicht gemacht)
Code:
;#Ed="D:\Ersetzung neue Rechtschreibung Wortliste.txt"
#Ed="/home/user/Desktop/tmp23regexreplace1.txt"

Define KrA  ; Kennzeichner regulärer Ausdruck
Define.s zuD, ZmrA, rA, Wed ; zu überprüfende Datei, (Zeile mit) regulärem Ausdruck, Wort ersetzen durch

;zuD="D:\umzuwandelnder Text.txt"
zuD="/home/user/Desktop/tmp23regexreplace2.txt"

If ReadFile(0, #Ed) ; Datei mit Suchmustern öffnen
  bom0 = ReadStringFormat(0)
 
  If ReadFile(1, zuD)  ; Öffnen der Datei erfolgreich
    bom1 = ReadStringFormat(1)       ; setzt den Dateizeiger an das Ende der BOM
    Define Di.s = ReadString(1, bom1 | #PB_File_IgnoreEOL)
;     Define *P, Dl, Di.s ; Puffer, Dateilänge, Dateiinhalt
;     Dl=Lof(1)
;     *P=AllocateMemory(Dl, #PB_Memory_NoClear) ;   
;     If *P
;       ReadData(1, *P, Dl) ; Datei ab Adresse *P in den Puffer schreiben
;       Di=PeekS(*P)    ; liest den kompletten Puffer aus und schreibt
;       FreeMemory(*P)  ; ihn in die Zeichenkette Di
;     EndIf
    Debug "di: " + Di
    CloseFile(1)
  EndIf
 
  While Not Eof(0)
    ZmrA=ReadString(0, bom0) ; Zeile mit regulärem Ausdruck einlesen
    rA=StringField(ZmrA, 1, " ")  ; regulären Ausdruck extrahieren
    Wed=StringField(ZmrA, 2, " ") ; Ersetzungsausdruck extrahieren
    KrA=CreateRegularExpression(#PB_Any, rA)
    Di=ReplaceRegularExpression(KrA, Di, Wed)
    Debug Di
    FreeRegularExpression(KrA)
  Wend
  CloseFile(0)  ; Datei mit Suchmustern schließen
EndIf

zuD2.s = zuD + ".2.txt"
If CreateFile(2, zuD2) ; Pfad zur Zieldatei
  WriteStringFormat(2, #PB_UTF8)
  WriteString(2, Di): CloseFile(2)
EndIf

_________________
my pb stuff..
Bild..jedenfalls war das mal so.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Fehler mit regulärem Ausdruck
BeitragVerfasst: 09.10.2019 21:31 
Offline

Registriert: 13.05.2017 01:44
Danke für Eure Antworten. Ich bin kurz nach dem Post selbst auf den Fehler gekommen, es lag tatsächlich an dem fehlenden ReadStringFormat für die erste Datei. Was ich nicht so gut am Debugger finde, ist, daß er die BOM nicht anzeigt, wenn man mit dem Mauszeiger auf die Variable rA fährt, auch nicht in irgendeiner symbolischen Form. Der VisualBasic-Debugger tut das zumindest bei CR und LF, wenn der Font das zuläßt, also grundsätzlich könnte man wohl auch Sonderzeichen irgendwie grafisch sichtbar machen. Weil sonst sieht es so aus, als würde die Variable genau den Inhalt haben, der gewünscht ist, und irrt sich sehr.
Zitat:
Bist du sicher das du die Dateien als UTF-16 (#PB_Unicode) lesen willst? Normalerweise würdest du den BOM auslesen und dann als Format-Flag weiterreichen.
Ich bin mir nicht sicher, was Du damit meinst. Die Dateien sind jedenfalls beide im UTF-16-Format – alle meine Textdateien sind das, weil ich häufig bi- und multilinguale Texte habe (Deutsch/Russisch/Altgriechisch gemischt).
Überhaupt fühle ich mich beim Thema "BOM" noch nicht sattelfest; ich weiß nur das, was die Hilfe dazu schreibt, also daß sie bei UTF-16-Dateien in der Regel am Dateianfang steht. Wie man am besten mit ihr umgeht, wenn man den String, der die gesamte Datei enthält, manipulieren will (Überspringen, Ausschneiden/Kopieren und nach der Veränderung wieder einfügen) – keine Ahnung. Was ich allerdings beobachtet habe, ist, daß es offenbar nicht genügt,
Code:
WriteStringFormat(2, #PB_Unicode)
einfach vor
Code:
WriteString(2, Di): CloseFile(2)
zu setzen, wie am Ende meines Kodes. Manchmal (aber nicht immer) tauchen in der durch CreateFile erzeugten neuen (manipulierten) Datei seltsame asiatische Zeichen auf.

_________________
Windows 7 x64; geposteter Kode bezieht sich (sofern nicht anders angegeben) immer auf das aktuellste PureBasic 64-Bit

Erst wenn man es seiner Schwiegermutter erklären kann, hat man es verstanden.
As gsündeste is oiwei guad essn und dringa und ned grang wern.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Fehler mit regulärem Ausdruck
BeitragVerfasst: 09.10.2019 21:59 
Offline
Benutzeravatar

Registriert: 20.04.2006 09:50
Das Format-Flag das du bei WriteStringFormat() verwendest müsstest du dann auch bei WriteString() mit angeben.

_________________
my pb stuff..
Bild..jedenfalls war das mal so.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye