Fehler in ReplaceString

Hier werden, insbesondere in den Beta-Phasen, Bugmeldungen gepostet. Das offizielle BugForum ist allerdings hier.
Benutzeravatar
ProgOldie
Beiträge: 236
Registriert: 19.05.2012 17:09
Computerausstattung: Windows11, Arduinos, Pi3, PureBasic 6.02

Fehler in ReplaceString

Beitrag von ProgOldie »

In einem seltenen Fall funktioniert ReplaceString() nicht richtig. Angenommen, man will jeweils zwei aufeinanderfolgende Leerzeichen durch ein einziges Leerzeichen ersetzen, so werden 3 aufeinanderfolgende Leerzeichen nicht korrekt ins nur eins umgewandelt.

Code: Alles auswählen

EnableExplicit
;Ersetze 2 oder mehr Leerzeichen durch ein einziges

Define Teststring.s,k.i
Teststring="Hallo, String mit vielen              Leerzeichen     *"
Teststring=ReplaceString(Teststring,"  "," ")
MessageRequester("wrong",Teststring)
Offensichtlich wird folgendes Verfahren angewandt: Zunächst wird das erste Auftreten von " " (2Leerzeichen") gesucht und durch ein einzelnes Leerzeichen ersetzt.Wenn das doppelte Leerzeichen an der Stelle k im String beginnt, wird anschließend nach weiteren Leerzeichen ab der Stelle k+2 [allgemeiner k+Länge(Findstring) ] weitergesucht. Richtig aber wäre eine weitere Suche ab der Stelle k+1 bzw. allgemeiner k+länge(Ersatzstring). Der Fehler tritt immer dann auf, wenn der Suchstring eine geringere Länge als der Ersatzstring hat und gleichartige Zeichen aufeinanderfolgen.

Der Fehler fällt in anderen als dem geschildertem Fall nicht auf. Würde die folgende Suche bei k+länge(Ersatzstring) beginnen, wäre auch im geschilderten Fall das Ergebnis korrekt und bisherige Fälle funktionierten weiterhin. Es würde lediglich eine etwas geringere Geschwindigkeit vorliegen, da pro Auftreten jeweils 1 Zeichen mehr untersucht werden müsste.

Der geschilderte Fall ist übrigens wichtig bei der Aufsplittung eines String mit Leerzeichen als Trennzeichen. Wenn dort mehrere Leerzeichen aufeinanderfolgen, will man das auf ein einzelnes reduziert haben.

Natürlich kann man das gewünschte Verhalten mit Findstring und Replacestring bzw. durch wiederholten Aufruf von Replacestring() nachbilden. Viel einfacher aber wäre die geschilderte Änderung in der Codierung von ReplaceString().
Windows10 / PB5.70 / Arduino (-Due) / Raspberry Pi3 /Linux Mint 18
Benutzeravatar
helpy
Beiträge: 636
Registriert: 29.08.2004 13:29

Re: Fehler in ReplaceString

Beitrag von helpy »

Das ist in meinen Augen genau das erwartete Verhalten.
Das macht auch jedes Textverarbeitungsprogramm und jeder Editor so.

Das was Du möchtest kannst Du mit regulären Ausdrücken machen:

Code: Alles auswählen

EnableExplicit
;Ersetze 2 oder mehr Leerzeichen durch ein einziges

Define Teststring.s, rexPurgeSpaces
Teststring="Hallo, String mit vielen              Leerzeichen     *"
rexPurgeSpaces = CreateRegularExpression(#PB_Any, "  +")
Debug Teststring
Teststring=ReplaceRegularExpression(rexPurgeSpaces,Teststring," ")
Debug Teststring
Oder wie Du schon gesagt hast, mit wiederholtem Aufruf:

Code: Alles auswählen

EnableExplicit
;Ersetze 2 oder mehr Leerzeichen durch ein einziges

Define Teststring.s
Teststring="Hallo, String mit vielen              Leerzeichen     *"
Debug Teststring
While FindString(Teststring, "  ") > 0
  Teststring = ReplaceString(Teststring, "  ", " ")
Wend
Debug Teststring
Windows 10
PB Last Final / (Sometimes testing Beta versions)
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Fehler in ReplaceString

Beitrag von STARGÅTE »

Sehe ich genauso wie helpy.

ReplaceString() sollte nicht den Ersetzungsstring wiederum zur nachfolgenden Suche hinzuziehen, anderen Falls würde es sogar zu einer endlosen Rekursion kommen, wenn man ABC durch ABC ersetzt.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
ProgOldie
Beiträge: 236
Registriert: 19.05.2012 17:09
Computerausstattung: Windows11, Arduinos, Pi3, PureBasic 6.02

Re: Fehler in ReplaceString

Beitrag von ProgOldie »

ReplaceString() sollte nicht den Ersetzungsstring wiederum zur nachfolgenden Suche hinzuziehen, anderen Falls würde es sogar zu einer endlosen Rekursion kommen, wenn man ABC durch ABC ersetzt.
Das wäre aber nach meinem Vorschlag nicht der Fall:
TestABCDEF:Treffer bei k=5; nächste Überprüfung bei TestABCDEF mit k=5+Länge("ABC")=5+3=8, also ab 'D'.
Endlose Rekursion könnte immerhin eintreten, wenn der Ersetzungsstring leer wäre, weil er dann die Länge 0 hätte.

Aber: Wenn's denn so sein soll, ich kann auch mit der Nachbildung von helpy durch mehrfache Anwendung leben.
Windows10 / PB5.70 / Arduino (-Due) / Raspberry Pi3 /Linux Mint 18
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: Fehler in ReplaceString

Beitrag von Nino »

ProgOldie hat geschrieben:Der geschilderte Fall ist übrigens wichtig bei der Aufsplittung eines String mit Leerzeichen als Trennzeichen. Wenn dort mehrere Leerzeichen aufeinanderfolgen, will man das auf ein einzelnes reduziert haben.
Kommt wohl darauf an, wer "man" ist. :-)
helpy hat geschrieben:Das ist in meinen Augen genau das erwartete Verhalten.
Das macht auch jedes Textverarbeitungsprogramm und jeder Editor so.
Ja, und das ist auch gut so.

@ProgOldie:
Wenn ReplaceString() so funktionieren würde wie von Dir vorgeschlagen, das wäre ein Bug!
Denn dann wäre es z.B. unmöglich, damit zuverlässig jeweils 2 hintereinander liegende Leerzeichen in einem String durch 1 Leerzeichen zu ersetzen. Stattdessen würden zwangsweise immer alle hintereinander liegenden Leerzeichen ersetzt. Das ist aber nicht immer erwünscht. D.h. bei der von Dir vorgeschlagenen Funktionsweise wäre dem Programmierer die Kontrolle über das entzogen, was ReplaceString() genau macht. Das kann keinesfalls Sinn der Sache sein.

Kein Bug :!:
Antworten