Seite 1 von 1

Fehler in ReplaceString

Verfasst: 13.01.2015 14:39
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().

Re: Fehler in ReplaceString

Verfasst: 13.01.2015 15:32
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

Re: Fehler in ReplaceString

Verfasst: 13.01.2015 18:07
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.

Re: Fehler in ReplaceString

Verfasst: 13.01.2015 21:52
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.

Re: Fehler in ReplaceString

Verfasst: 13.01.2015 22:28
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 :!: