ReplaceString nur so und so oft mal (wie bei RemoveString) ?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
padawan
Beiträge: 17
Registriert: 17.06.2009 15:59

ReplaceString nur so und so oft mal (wie bei RemoveString) ?

Beitrag 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
Zuletzt geändert von padawan am 17.08.2010 23:32, insgesamt 1-mal geändert.
Benutzeravatar
TomS
Beiträge: 1508
Registriert: 23.12.2005 12:41
Wohnort: München

Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin

Beitrag 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")
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7035
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin

Beitrag 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!
Zuletzt geändert von STARGÅTE am 17.08.2010 01:25, insgesamt 1-mal geändert.
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
Kiffi
Beiträge: 10719
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin

Beitrag 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)
a²+b²=mc²
Benutzeravatar
padawan
Beiträge: 17
Registriert: 17.06.2009 15:59

Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin

Beitrag 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
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin

Beitrag 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$
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Benutzeravatar
padawan
Beiträge: 17
Registriert: 17.06.2009 15:59

Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin

Beitrag von padawan »

Die sind alle cool, die Lösungen :allright: 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.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7035
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin

Beitrag 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.
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
padawan
Beiträge: 17
Registriert: 17.06.2009 15:59

Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin

Beitrag 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
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7035
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: ReplaceString nur so und so oft mal (wie bei RemoveStrin

Beitrag 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 ...
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
Antworten