[UPDATE] ReplaceStrings() - Mehrere Strings auf einmal ers..

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

[UPDATE] ReplaceStrings() - Mehrere Strings auf einmal ers..

Beitrag von AND51 »

Hallo!

Ich habe eine Prozedur geschrieben, die mehrere Strings auf einmal ersetzt. Es wird eine ausgewogene Kombination aus einer For-Schleife und dem PB-Befehl ReplaceString() verwendet. <)

Angenommen, ihr habt einen String, der sieht so aus:

Code: Alles auswählen

String$="%x von %y Dateien markiert, Größe: %size"
%x: wie viele Dateien markiert
%y: Anzahl Gesamtdateien
%size: Gesamtgröße

Dann musste man bisher immer schreiben:

Code: Alles auswählen

ReplaceString(ReplaceString(ReplaceString($String, "%x", "9"), "%y", "10"), "%size", "22 MB")
Als Beispiel werden hier fixe Angaben verwendet: 9 von 10 Dateien markiert, Größe: 22 MB


OK, hier nun die Prozedur und darunter der kleine, neue Aufruf, der en obigen 3x ReplaceString() ersetzt:

Code: Alles auswählen

Procedure.s ReplaceStrings(String$, StringsToFind$, StringsToReplace$, Separator$="|", Mode=0, StartFrom=1)
	Protected n.l
	
	For n=1 To CountString(StringsToFind$, Separator$)+1
		String$=ReplaceString(String$, StringField(StringsToFind$, n, Separator$), StringField(StringsToReplace$, n, Separator$), Mode, StartFrom)
	Next
	ProcedureReturn String$
EndProcedure



Debug ReplaceStrings("Datei %x von %y, Größe: %size", "%x|%y|%size", "9|10|22 MB")
Das wars, diese eine Zeile ist nur nötig. Die StringsToFind$ und StringsToReplace$ gibt man einfach an wie Pattern bei einem OpenFileRequester().

Lustigerweise und einfachheitshalber habe ich die Funktionen und Parameter genauso wie PB genannt, nur halt von allem die Mehrzahl:
ReplaceString() => ReplaceStrings(), usw...

Wer will, kann sich ja auch ein eigenes Trennzeichen einbauen, wenn er nicht auf das | verzichten will.



Edit: Code optimiert, kompatibel mit allen gängigen Versionen von PB.
Edit 2: Code optimiert, kompatibel mit PB 4.0 oder höher. Es werden außerdem die optionalen Parameter Mode und StartFrom von ReplaceString() unterstützt!
Zuletzt geändert von AND51 am 17.11.2006 19:50, insgesamt 3-mal geändert.
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: ReplaceStrings() - Mehrere Strings aus einmal ersetzen

Beitrag von Kiffi »

> Ich habe eine Prozedur geschrieben, die mehrere Strings auf einmal
> ersetzt.

Schöne Idee! Danke dafür! :allright:

Einen kleinen Verbesserungsvorschlag habe ich noch: Wenn Du Deine
CountString()-Schleife um 1 erhöhst, dann brauchst Du zuvor nicht
StringToFind und StringToReplace mit einem abschliessenden Separator
erweitern. Des weiteren kannst Du den Separator ja auch optional
angeben lassen. Wenn er nicht angegeben wird, verwendest Du das '|',
ansonsten den angegebenen Separator.

Code: Alles auswählen

Procedure.s ReplaceStrings(String$, StringsToFind$, StringsToReplace$, Separator$="|")
  Protected n.l
  For n=1 To CountString(StringsToFind$, Separator$)+1
    String$=ReplaceString(String$, StringField(StringsToFind$, n, Separator$), StringField(StringsToReplace$, n, Separator$))
  Next
  ProcedureReturn String$
EndProcedure

String$="%x von %y Dateien markiert, Größe: %size"

Debug ReplaceStrings(String$, "%x|%y|%size", "9|10|22 MB")

Debug ReplaceStrings(String$, "%x§%y§%size", "9§10§22 MB", "§")
Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Re: ReplaceStrings() - Mehrere Strings aus einmal ersetzen

Beitrag von AND51 »

Kiffi hat geschrieben:Wenn Du Deine
CountString()-Schleife um 1 erhöhst, dann brauchst Du zuvor nicht
StringToFind und StringToReplace mit einem abschliessenden Separator
erweitern.
Deswegen hat das ohne die manuelle Erweiterung nie funktioniert... :o

Aber naja bitte! Und danke für das lob!
Das ich die Proc im Zuge eines 3.94 Projekt entwickelt habe, kann ich leider keine optionalen Paramter direkt benutzen.

Ich hoffe, die Proc findet Anwendung... :allright:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: ReplaceStrings() - Mehrere Strings aus einmal ersetzen

Beitrag von Kiffi »

> Das ich die Proc im Zuge eines 3.94 Projekt entwickelt habe, kann ich
> leider keine optionalen Paramter direkt benutzen.

oh, habe ich nicht gesehen :oops:

(ist aber auch ziemlich klein, deine sig)

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Ist ja nicht so schlimm, siehs mal positiov, wie haben jetzt eine 3.94- version und eine 3.94+ version. was will man mehr? <)
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Benutzeravatar
Then
Beiträge: 287
Registriert: 06.09.2004 13:26
Wohnort: Siegen

Beitrag von Then »

Eine gute Idee ! Ich habe auch schon damit angefangen neue Striegfield Befehle zu schreiben, aber mein derzeitiges Projekt hat mich komplett in Anspruch genommen. Aber für ne neue Userlib wäre das mal ne Maßnahme. Meine Befehle :

Code: Alles auswählen

AddStringField(String, StringToFind, Wert, Trenn.) <= Addiert einem Feld einen Wert hinzu
SubStringField(String, StringToFind, Wert, Trenn.) <= Subtrahiert den WERT von einem Feld
SwapStringField(String1, Feld1, String2, Feld2, Trenn.) <= tauscht die Felder im Stringfield gegeneinander aus
...
Sowas könnte man bestimmt noch gebrauchen ... ich jedenfalls brauchte das :)
PB 6.10LTs / Windows 11 64Bit 25H2

... ich mache dazu keine Aussage, weil ich mich damit selbst belasten könnte !
Benutzeravatar
AND51
Beiträge: 5220
Registriert: 01.10.2005 13:15

Beitrag von AND51 »

Schreib doch deinen Code schon einmal hier rein, dann können wir es auch schon ohne UserLib benutzen! Deine Procs hören sich interessant an! :allright:
PB 4.30

Code: Alles auswählen

Macro Happy
 ;-)
EndMacro

Happy End
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

wenn ihr das als include zusammensetzt, muss es auch keine UserLib werden.

...manche leute benutzen nähmlich keine...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

Kaeru Gaman hat geschrieben:wenn ihr das als include zusammensetzt, muss es auch keine UserLib werden.
... und dann ab in Thomas' IncludePack :mrgreen:

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
remi_meier
Beiträge: 1078
Registriert: 29.08.2004 20:11
Wohnort: Schweiz

Beitrag von remi_meier »

Hab für mein jaPBdoc etwas Ähnliches gebastelt, was mehrere Zeichen
mit mehreren Strings ersetzt. Ich hatte zuerst viele ReplaceStrings()
hintereinander um einzelne Sonderzeichen mit dem HTML-Namen zu
ersetzen:

Code: Alles auswählen

;** s replacechars
;* a structure holding the chars and their strings
;* for replacement in ReplaceMultipleChars()
Structure REPLACECHARS
  chars.c[50]    ;* up to 50 chars can be defined
  strings.s[50]  ;* the replacement strings for the chars
EndStructure



;** replacemultiplechars
;* Replaces multiple chars with strings in one string
;** .String: String where chars shall be replaced
;** .*characters: A structure with chars and strings which 
;* shall be replaced by what
Procedure.s ReplaceMultipleChars(String.s, *Characters.REPLACECHARS)
  Protected *Char.CHARACTER, Result.s, z.l, Add.s, found.l
  
  If (Not String) Or (Not *characters)
    ProcedureReturn String
  EndIf
  
  *Char = @String
  While *Char\c <> 0
    Add = ""
    found = #False
    
    For z = 0 To 49
      If *Char\c = *Characters\chars[z]
        Add = *Characters\strings[z]
        found = #True
        Break
      ElseIf *Characters\chars[z] = 0
        Break
      EndIf
    Next
    
    If Not found
      Add = Chr(*Char\c)
    EndIf
    
    Result + Add
    *Char + SizeOf(CHARACTER)
  Wend
  
  ProcedureReturn Result
EndProcedure
Auch wenns nicht wirklich das Gleiche ist, einen weiteren Thread dazu
zu eröffnen, fand ich etwas übertrieben :)
Antworten