Seite 1 von 2
ReplaceString nur so und so oft mal (wie bei RemoveString) ?
Verfasst: 17.08.2010 00:58
von padawan
Guten Abend,
ich suche eine Möglichkeit, nicht alle Vorkommen eines Substrings in einem String durch einen Ersatzstring zu ersetzen, sondern nur eine bestimmte Anzahl von Vorkommen. Gibt es dafür schon einen Workaround - oder wie würdet ihr das angehen? Also, als Beispiel, im String "Jeder.muss.mal.abtreten. Schade!" will ich alle Punkte durch ein Leerzeichen ersetzen, außer dem letzten Punkt nach "abtreten", der soll bleiben.
Grüße, padawan
Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin
Verfasst: 17.08.2010 01:18
von TomS
Wenn du N Zeichen(ketten) ersetzen willst, musst du wohl zählen.
Falls du immer nur den letzten Punkt behalten möchtest suchst du mit FindString das letzte Vorkommen und splittest an dieser Stelle. Dann ersetzt du im ersten Teil alles und fügst die beiden Teile wieder mit einem Punkt dazwischen zusammen.
Code: Alles auswählen
Procedure.s Replace(string.s, find.s, replace.s, separator.s)
Protected findstringpos.i
Protected part1.s
Protected part2.s
While FindString(string, find, findstringpos)
findstringpos = FindString(string, find, findstringpos)+1
Wend
part1 = Left(string, findstringpos-2 )
part1 = ReplaceString(part1, find, replace)
part2 = Right(string, Len(string)-findstringpos+1)
ProcedureReturn part1 + separator + part2
EndProcedure
Debug Replace("a.b.c.d.txt", ".", " ", ".")
Debug Replace("Jeder.muss.mal.abtreten. Schade!", ".", " ", ".")
Debug Replace("Jeder.muss.mal.abtreten. Schade!", ".", " ", ". Das ist")
Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin
Verfasst: 17.08.2010 01:22
von STARGÅTE
Dafür würde sich ein Regulärer Ausdruck eignen:
Code: Alles auswählen
#RegularExpression = 1
If CreateRegularExpression(#RegularExpression, "\.(?=.*\.)")
String$ = "Jeder.muss.mal.abtreten. Schade!"
NewString$ = ReplaceRegularExpression(#RegularExpression, String$, " ")
Debug NewString$
EndIf
oder du zerlegst die Zeichenkette mit StringField() bei jedem Punkt, und baust sie dann mit Leerzeichen wieder zusammen, bis zum vorletzten, dann ein Punkt und das Letze. (ähnlich wie mein vorposter)
oder du arbeitest direkt im Speicher und gehst den String von hinten nach vorne durch und killst alle Punkte nach dem ersten:
Code: Alles auswählen
Procedure Test(*Character.Character)
Protected *Position.Character = *Character + MemoryStringLength(*Character)
Protected Kill
While *Position >= *Character
If *Position\c = '.'
If Kill : *Position\c = ' ' : EndIf
Kill = #True
EndIf
*Position - SizeOf(Character)
Wend
EndProcedure
String$ = "Jeder.muss.mal.abtreten. Schade!"
Test(@String$)
Debug String$
die direkte Variante im Speicher ist wohl das schnellste, da es ohne Temporäre Strings arbeitet!
Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin
Verfasst: 17.08.2010 01:23
von Kiffi
hier 'meiner' (
Original von superadnim):
Code: Alles auswählen
Procedure.s StringReplace( szStr.s, szStrSrc.s, szStrRepl.s, dwTimes=1 )
Protected dwPos, i
For i=1 To dwTimes
dwPos = FindString(szStr, szStrSrc, 1)
If dwPos
szStr = Left(szStr, dwPos-1) + szStrRepl + Right(szStr, (Len(szStr)-dwPos-Len(szStrSrc)+1) )
Else
Break
EndIf
Next
ProcedureReturn szStr
EndProcedure
myString.s = "1.2.3.4.5"
Debug StringReplace("1.2.3.4.5", ".", " ", CountString(myString, ".") - 1)
Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin
Verfasst: 17.08.2010 01:52
von padawan
Ui - schon ne Menge gute Vorschläge, vielen Dank! Ich arbeite das mal ab und melde mich a.s.a.p zurück!
Grüße, padawan
Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin
Verfasst: 17.08.2010 07:35
von hjbremer
im Prinzip wie Stargates Vorschlag, nur etwas anders
Code: Alles auswählen
Structure charArray
c.c[0]
EndStructure
Procedure.s Test1(x$)
Protected j, k, *c.charArray = @x$
Repeat
If *c\c[j] = '.'
*c\c[j] = ' '
k = j
EndIf
j + 1
Until Not *c\c[j]
If k: *c\c[k] = '.': EndIf
ProcedureReturn x$
EndProcedure
String$ = "Jeder.muss.mal.abtreten. Schade!"
string$ = Test1(string$)
Debug String$
Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin
Verfasst: 17.08.2010 22:43
von padawan
Die sind alle cool, die Lösungen

vielen Dank für euer Input. Für mich persönlich ist die Lösung von Stargate mit dem Regulären Ausdruck am reizvollsten, weil ich sowieso gerade versuche, mich mit dem Thema anzufreunden. Diesen Ausdruck kann ich mir jetzt mal richtig genüsslich auf der Zunge zergehen lassen.
Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin
Verfasst: 17.08.2010 22:55
von STARGÅTE
JO, aber Reguläre Ausdrücke sind trotzdem mit vorsicht zu genießen.
Es ist nicht immer gesagt das diese am schnellsten sind ...
"\.(?=.*\.)" bedeutet in worten: Suche nach einem Punkt "\.", nachdem "(?=)" eine unbestimmte lange Zeichenfolge ".*" kommt, und wiederum ein Punkt enthält "\." ...
Beachte bitte noch:
Wichtig: Die PCRE Lizenz erfordert, dass eine Copyright-Notiz und der Lizenz-Text selbst in jede Software integriert werden, welche die Bibliothek beinhaltet. Wenn also die Bibliothek in einer Software verwendet wird, welche öffentlich zugänglich gemacht wird, dann MUSS die oben verlinkte Lizenz in die Software integriert werden.
Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin
Verfasst: 17.08.2010 23:20
von padawan
Danke für die Erklärung im Detail, Stargate. Ist schon extrem komprimiert, soviel Logik auf so wenige Zeichen. Kannst du eine gute Einführung in das Thema empfehlen? Ich meine, man kann das zwar alles unter
http://www.pcre.org/pcre.txt nachlesen, aber das ist nicht gerade, was ich unter einer guten Einführung verstehe... ist ja auch nicht als solche gedacht.
Danke auch für den Hinweis mit der Lizenz.
Grüße, padawan
Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin
Verfasst: 17.08.2010 23:25
von STARGÅTE
Ich habe das hier genutzt:
RegExp-Tutorial
Ist zwar eigentlich für PHP gedacht, trotzdem sind die meisten Sachen identisch mit PB ...