Seite 1 von 2
Frage zu 'ReplaceString()'
Verfasst: 17.03.2017 18:15
von blastar
Hallo,
ich habe da mal eine Frage zu 'ReplaceString()'.
Nachdem der 'ReplacementString$' im 'String$ ' eingefuegt wurde, wird dieser leider nicht mehr fuer nachfolgende Checks beachtet.
hier mal ein schnelles Beispiel mit '0':
Code: Alles auswählen
string.s = "0000000000"
string = ReplaceString(string, "00", "0")
Debug string ; = 00000
Das sollte im idealen Fall (so stelle ich mir das vor) eine einzelne '0' ausgeben... leider gibt das '00000' aus. Ist das korrekt so (getestet unter 4.62 - 5.60) oder muss ich dazu einen anderen Befehl nutzen?
Hintergrund: ich habe ein Log-Datei welche ich auslesen will. Die tabellenartige Formatierung ist durch das x-fache einfuegen von Space-zeichen erfolgt. Um den Befehl 'StringField()' gezielt zu nutzen muss ich aber erstmal alle sich wiederholenden Space-zeichen durch ein einziges ersetzen. Im Moment nutze ich den Umweg 'ReplaceString()' mehrfach aufzurufen... gib es da eine einfachere Loesung?
Re: Frage zu 'ReplaceString()'
Verfasst: 17.03.2017 18:48
von NicTheQuick
Hab grad was dafür gebastelt. Vorsicht: Wildes Gepointere!
Code: Alles auswählen
Procedure.s MyStringField(*string, index.i, separator.s)
Protected *sep.Character = @separator
Protected *c.Character = *string, *begin
While *c\c And *c\c = *sep\c
*c + SizeOf(Character)
Wend
*begin = *c
While *c\c
If *c\c = *sep\c
index - 1
If index = 0
ProcedureReturn PeekS(*begin, (*c - *begin) / SizeOf(Character))
EndIf
While *c\c And *c\c = *sep\c
*c + SizeOf(Character)
Wend
*begin = *c
Continue
EndIf
*c + SizeOf(Character)
Wend
If index = 1
ProcedureReturn PeekS(*begin, (*c - *begin) / SizeOf(Character))
Else
ProcedureReturn ""
EndIf
EndProcedure
zeile.s = " Spalte1 Spalte2 Spalte3"
Debug MyStringField(@zeile, 1, " ")
Debug MyStringField(@zeile, 2, " ")
Debug MyStringField(@zeile, 3, " ")
Re: Frage zu 'ReplaceString()'
Verfasst: 17.03.2017 19:06
von Sicro
Code: Alles auswählen
; --------------------------------------
; Beim Programmstart
; \S bedeutet: Alles außer Leerzeichen
; * bedeutet: beliebige Anzahl, auch keines Mal
; \s bedeutet: Leerzeichen
; + bedeutet: Es muss mindestens einmal vorkommen
; () bedeutet: Gruppierung
RegEx = CreateRegularExpression(#PB_Any, "\s*(\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s*")
If Not RegEx
Debug "Fehler: CreateRegularExpression"
End
EndIf
; --------------------------------------
TabellenZeile$ = " bla1 bla2 bla3 bla4 "
If ExamineRegularExpression(RegEx, TabellenZeile$) And NextRegularExpressionMatch(RegEx)
Debug RegularExpressionGroup(RegEx, 1) + " " +
RegularExpressionGroup(RegEx, 2) + " " +
RegularExpressionGroup(RegEx, 3) + " " +
RegularExpressionGroup(RegEx, 4)
EndIf
; Wenn der beim Programmstart erstellte RegEx nicht mehr benötigt wird,
; diesen freigeben. Beim Programmende wird dieser automatisch freigegeben.
FreeRegularExpression(RegEx)
Edit:
Bezüglich ReplaceString(): Dieser Befehl geht nicht Zeichen für Zeichen durch den String, sondern springt entsprechend der Länge von ErsetzString weiter.
Re: Frage zu 'ReplaceString()'
Verfasst: 17.03.2017 19:21
von Josh
Dann mach ich bei der Bastelstunde auch mal mit
Code: Alles auswählen
Structure CHARARRAY
c.c[0]
EndStructure
Procedure.s EliminateDoubleSpaces (String$)
Define *Read .CHARARRAY = @String$
Define *Write.CHARARRAY = @String$
While *Read\c <> 0
If *Read\c[0] = ' ' And *Read\c[1] = ' '
*Read + SizeOf(Character)
Else
*Write\c = *Read\c
*Read + SizeOf(Character)
*Write + SizeOf(Character)
EndIf
Wend
*Write\c = 0
ProcedureReturn String$
EndProcedure
Debug "*" + EliminateDoubleSpaces (" Pure Basic ") + "*"
Re: Frage zu 'ReplaceString()'
Verfasst: 17.03.2017 19:43
von juergenkulow
Hallo blastar,
Code: Alles auswählen
Declare.s ErsetzeMehrfachZeichen(string.s,Zeichen.s)
string.s = "0000000000LOG-TEXT"
; string = ReplaceString(string, "00", "0") : Debug string ; 00000LOG-TEXT
string = ErsetzeMehrfachZeichen(string,"0") : Debug string ; 0LOG-TEXT
string= Space(50)+" Log-Text 2" : Debug ErsetzeMehrfachZeichen(string," ") ; Log-Text 2
string= " Log Text 3" : Debug ErsetzeMehrfachZeichen(string," ") ; Log Text 3
string=Space(50)+" Log Text 4"+ Space(50)+" Teil 2" : Debug ErsetzeMehrfachZeichen(string," ") ; Log Text 4 Teil 2
Procedure.s ErsetzeMehrfachZeichen(string.s,Zeichen.s) ; Procedure übernimmt den String und das Leerzeichen oder Nullzeichen und gibt einen String als Ergbenis zurück.
Protected PositionDoppelZeichen=FindString(string,Zeichen+Zeichen) ; Es wird die erste Postion im String ermittelt, wo das Zeichen doppelt vorkommt, sonst Null.
While PositionDoppelZeichen ; Wiederhole solange Zeichen doppelt vorkommen.
string=Left(string,PositionDoppelZeichen-1)+Zeichen+LTrim(Mid(string,PositionDoppelZeichen),Zeichen) ; Füge den neuen String aus dem linken Teil, der beim erstenmal leer ist,
; einmalig das ersetzte Zeichen und dem rechten Teil des Strings jedoch ohne die führenden ersetzten Zeichen zusammen.
PositionDoppelZeichen=FindString(string,Zeichen+Zeichen) ; Finde die nächste Position im String, wo das Zeichen doppelt vorkommt, sonst Null
Wend ; while PositionDoppelZeichen
ProcedureReturn string ; Ergebnis angeben.
EndProcedure
Re: Frage zu 'ReplaceString()'
Verfasst: 17.03.2017 20:17
von Kiffi
Code: Alles auswählen
Define OldString.s
Define String.s = "0000000000"
Repeat
OldString = String
String = ReplaceString(String, "00", "0")
Until String = Oldstring
Debug String
Grüße ... Peter
Re: Frage zu 'ReplaceString()'
Verfasst: 17.03.2017 21:54
von blastar
Danke fuer die schnellen und umfangreichen Antworten!

Da waren ja schon echt heftigen Loesungen dabei!
Das einlesen der Datein erfolgt im Hintergrund per Threading, sind Pointer sicher oder muss ich da noch zusaetzlich was beachten?
Die Loesung mit 'CreateRegularExpression' ist interessant, ich wusste garnicht das es sowas gibt in PB, hat das Nachteile oder gibt es Wechselwirkungen?
Die Ansatze mit 'Bordmitteln' haben auch was... zwar nicht die schnellsten aber am einfachsten zu lesen.
Re: Frage zu 'ReplaceString()'
Verfasst: 17.03.2017 23:27
von GPI
Sicro hat geschrieben:Edit:
Bezüglich ReplaceString(): Dieser Befehl geht nicht Zeichen für Zeichen durch den String, sondern springt entsprechend der Länge von ErsetzString weiter.
Was auch Sinn macht, weil ansonsten man leicht eine Endlosschleife bauen kann.
Re: Frage zu 'ReplaceString()'
Verfasst: 17.03.2017 23:33
von #NULL
blastar hat geschrieben:Im Moment nutze ich den Umweg 'ReplaceString()' mehrfach aufzurufen... gib es da eine einfachere Loesung?
das is doch schon einfach
Code: Alles auswählen
string.s = "0000000000_0_000_00"
While FindString(string, "00")
string = ReplaceString(string, "00", "0")
Wend
Debug string
oder mit regex
Code: Alles auswählen
Define s.s = "00_0000000000000_00000_00_0"
Define n = 0
Repeat
Dim match.s(0)
If CreateRegularExpression(0, "0{2,}") ; (two or more zeros)
n = ExtractRegularExpression(0,s,match())
If n
s = ReplaceString(s, match(i), "0") ; (replace repeated zeros with a single one)
EndIf
;Else
; Debug RegularExpressionError()
EndIf
;Debug s
Until Not n
Debug s
Re: Frage zu 'ReplaceString()'
Verfasst: 17.03.2017 23:37
von Sicro
blastar hat geschrieben:Das einlesen der Datein erfolgt im Hintergrund per Threading, sind Pointer sicher oder muss ich da noch zusaetzlich was beachten?
Solange der Thread die Daten verarbeitet, sollten die Daten nicht verändert werden.
blastar hat geschrieben:Die Loesung mit 'CreateRegularExpression' ist interessant, ich wusste garnicht das es sowas gibt in PB, hat das Nachteile oder gibt es Wechselwirkungen?
CreateRegularExpression ist im offiziellem Befehlssatz von PB seit Version 4.20 (23. Mai 2008) enthalten. Die Unterstützung von Gruppierungen gibt es seit PB-Version 5.30 (23. Juli 2014).
Mit regulären Ausdrücken lassen sich Daten von Datenansammlungen recht einfach extrahieren.
Wenn es dir sehr um Geschwindigkeit geht, dann ist eine für deine Aufgabe individuell erstellte und optimierte Lösung besser.
Du solltest dir mal die PB-Hilfe durchschauen. Möglicherweise sind dir noch weitere interessante Befehle unbekannt.