![]() |
Zeichen in String ersetzen
Betrifft:
DELPHI 5 Hi, VORGESCHICHTE: eine Freundin von mir hat für eine Studie Versuche mit diversen Programmen und Verfahren durchgeführt und diese Ergebnisse mit Programmen wie u.a. SPSS, Excel, usw. bearbeitet. Doch leider ist es zum Gau gekommen, da sie mehrere OriginalDateien überschrieben hat. (dauert jetzt zu lange das detailliert zu erklären). Die Daten sind zwar glücklicherweise noch einmal vorhanden, allerdings quer in 1 Datei verwurstet. PROBLEM: Jetzt hab ich ihr versprochen, ich würde ihr dabei helfen. Und hab versucht ein Programm zu entwickeln, das nach Zeichen sucht und diese Daten extrahieren oder zumindest erstmal trennen kann. Dabei soll bei Auftreten von 3 Zeichenkombinationen wie folgend verfahren werden: (für mich sind es nachher noch mehr, aber wenigstens die schon mal ..)
Delphi-Quellcode:
Ich hab jetzt seit Freitag immer wieder rumprobiert und mit mehreren Zeichenketten [s.o.] versucht.
procedure TForm1.Button8Click(Sender: TObject);
var Rest, s, TEX: string; Menge, Laenge, i: Integer; begin // Beispielkette S := '2,9,0171,,25,01640X0174,01747,23,,,,47X014747'; // S := '0,,25,01640X0174,01747,23,,,,47X014747'; // vorne gekürzte Kette bringt wieder andere Ergebnisse laenge := length(s); i := 0; Menge := 0; while i < laenge do begin inc(i); if (s[i] = 'X') and (s[i + 1] = '0') then // -> x0 begin if (s[i + 2] = '1') then // -> wenn X01 if Menge > 0 then begin TEX := TEX + ',' + ' Typ: A '; Menge := 0; end else TEX := TEX + ' Typ: A '; inc(i); end else //////////////////////////////////// if (s[i] = '0') and (s[i + 1] = '1') then // -> normaler 01 begin if Menge > 0 then begin TEX := TEX + ' Typ: B '; // Antworttyp Menge := 0; end else TEX := TEX + ',' + ' Typ: B '; // Antworttyp B inc(i); end else //////////////////////////////////// if (s[i] = ',') then // DOPPELTE Trenner finden begin inc(Menge); end else //////////////////////////////////// if Menge > 0 then begin Caption := s[i]; if Menge = 1 then TEX := TEX + ',' + s[i] else TEX := TEX + s[i]; Menge := 0; end else // alles andere TEX := TEX + s[i]; // alle anderen Zeichen end; // END WHILE Memo2.text := TEX; Memo1.text := S; end; // Ende Buttonfunktion Jedes Mal kamen andere, neue Verluste von Zeichen heraus. Aus der folgenden Zeichenkette z.B. 0,,25,01640X0174,01747,23,,,,47X014747 025 Typ: B 640 Typ: A174 Typ: B 747,2347 Typ: A 14747 kommt ^^ => d.h. (1. Doppelkomma => verschwindet ganz, Komma nach der 25 ist auch weg aus X01 wird aber die 1 dennoch übernommen Komma verschwindet, usw.) - aber das ist ja nicht richtig! Ich hab zwar jetzt an so vielen Stellen herumgeschraubt und verbessert, aber es will nicht komplett gelingen. Sieht vielleicht einer von Euch, woran es liegt? oder gibt es am Ende eine komplett einfachere Lösung? (ich habe keine Informatikerausbildung und Algorithmenentwicklung nicht nativ gelernt) Vielen Dank. |
AW: Zeichen in String ersetzen
Warum machst du es dir so schwer und versuchst alles gleichzeitig und auch "Mehrfachzeichen" mit Einzelzeichenoperationen zu verarbeiten?
Wenn/da es nicht auf's Tempo ankommt.
Delphi-Quellcode:
Und dannach
while ContainStr(S, ',,') do // nach zwei Durchläufen sind auch ',,,' nur noch ',' usw.
S := ReplaceStr(S, ',,', ',');
Delphi-Quellcode:
Man kann natürlich auch mit Pos/PosEx Zeichenketten suchen und über Delete+Insert ersetzen.
S := ReplaceStr(S, 'X01', '' Typ A: ');
S := ReplaceStr(S, '01', '' Typ B: '); Oder per RegEx nach "mehreren" Kommas suchen und sie durch ein ',' ersetzen. Mit 2 TStringList kann man auch Einzelzeilen und darin einzelne Teilstrings verarbeiten. Erste StringList für die Zeilen und dann jeweils eine Zeile in TStringList.CommaText oder TStringList.DelimitedText kopieren. In der 2. StringList alle Werte ohne inhalt löschen und in den einzelwerten das ReplaceStr anwenden. Nach auslesen und zurückschreiben des CommaText sind dann auch mehrfache Kommas aufgelöst (",," ist ein Leerstring zwischen den Kommas :zwinker:) und auch Kommas am Anfang und Ende sind weg (falls man beim Delete nicht den ersten und letzten Leerstring beibehält). |
AW: Zeichen in String ersetzen
Hi,
danke Dir für Deine Antwort: Allerdings muß ich dazu sagen, dass ich nur Delph 5 habe (und derzeit keinen Platz, um Lazarus oder eine Trial zu installieren, da ich gerade wichtige Planungsvideos auf meinem Laptop habe. Mhh, ja, sicher ist da viel auf einemal. Angefangen hatte ich auch erst nur mit den x01 und 01 (Typ A; Typ B) Zeichenketten und die bearbeitet. Das ging auch gut. Dann dachte ich mir .. Ok, die restlichen kannste ja noch mit Kommt ein Komma vor oder wenn, sogar mehrere ... und eigentlich würde ich das gerne mit Pointern machen (darum auch der Inc()-operator und einzelne Vegleich hier nochmal der VErsuch einer verkürzten Version der oben ... aber ich seh gerade, der Übersicht hilft das gar nicht. und die Ergebnisse sind auch wieder total andere: 0,,25,01640X0174,01747,23,,,,47X014747 wird zu 025, Typ B: ,640, Typ A: 174, Typ B: ,747,2347, Typ A: 14747
Delphi-Quellcode:
Mit Regex usw. kenn ich mich gar nicht aus. ...
procedure TForm1.Button9Click(Sender: TObject);
var Rest, s, TEX: string; Menge, Laenge, i: Integer; begin // 8 8 88 888 X01 S := '2,9,0171,,25,01640X0174,01747,23,,,,47X014747'; // S := '0,,25,01640X0174,01747,23,,,,47X014747'; // laenge := length(s); i := 0; Menge := 0; while i < laenge do begin inc(i); if s[i] = '5' then Caption := s[i]; if (s[i] = 'X') and (s[i + 1] = '0') then // -> x01 begin if (s[i + 2] = '1') then // wenn X01 TEX := TEX + ',' + ' Typ A: '; inc(i); end else //////////////////////////////////// // Caption := s[i]; if (s[i] = '0') and (s[i + 1] = '1') then // normaler 01 begin TEX := TEX + ',' + ' Typ B: '; inc(i); end else //////////////////////////////////// if (s[i] = ',') then // and (s[i + 1] = ',') then // DOPPELTE Trenner finden begin inc(Menge); end else //////////////////////////////////// if Menge > 0 then begin Caption := s[i]; if Menge = 1 then TEX := TEX + ',' + s[i] else TEX := TEX + s[i]; Menge := 0; // end else TEX := TEX + s[i]; // LAST CHANGE end; // END WHILE Memo2.text := TEX; Memo1.text := S; end; // |
AW: Zeichen in String ersetzen
Überprüfe bitte mal, ob die inc(i) immer korrekt sind. Inc(i) entspricht halt i := i + 1. Aber bei x01 verarbeitest Du doch drei Zeichen, demnach müsstest Du hier auch i := i + 3 machen statt inc(i).
Bei 01 wäre es dann i := i + 2; Bin mir nicht sicher, ob ich die Logik verstanden habe, es ist doch schon etwas zu früh - sorry spät ;-) Quelltext hab' ich mal angepasst und ein bisserl kommentiert, aber nicht getestet.
Delphi-Quellcode:
Kennt Delphi 5 schon die Funktion AnsiReplaceText aus der Unit StrUtils?
procedure TForm1.Button9Click(Sender: TObject);
var Rest, s, TEX: string; Menge, Laenge, i: Integer; begin // 8 8 88 888 X01 S := '2,9,0171,,25,01640X0174,01747,23,,,,47X014747'; // S := '0,,25,01640X0174,01747,23,,,,47X014747'; // laenge := length(s); i := 1; Menge := 0; while i < laenge do begin if s[i] = '5' then Caption := s[i]; // -> x01 if (s[i] = 'X') and (s[i + 1] = '0') then begin // wenn X01 if (s[i + 2] = '1') then begin TEX := TEX + ',' + ' Typ A: '; inc(i,2); end; end else //////////////////////////////////// // Caption := s[i]; // normaler 01 if (s[i] = '0') and (s[i + 1] = '1') then begin TEX := TEX + ',' + ' Typ B: '; inc(i); // Sonst finden wir im nächsten Durchgang die 1 und geben sie aus. end else //////////////////////////////////// // DOPPELTE Trenner finden if (s[i] = ',') then begin // and (s[i + 1] = ',') then inc(Menge); // Zählt die Anzahl der , ??? end else //////////////////////////////////// if Menge > 0 then begin // Hier kommen wir nur hin, wenn Menge > 0 // und keine der anderen Bedingungen erfüllt ist. // Kann hier jemals ein Komma ausgegeben werden, dass vor X01 bzw. 01 steht? Caption := s[i]; (* if Menge = 1 then TEX := TEX + ',' + s[i] // Ist Menge jedoch > 1, wird kein Komma ausgegeben. // Geht uns da nicht bei mehreren Kommas was verloren? // Hier dürfte die Ursache für das fehlende Komma zwischen 0 und 25 liegen. else TEX := TEX + s[i]; *) // Würde hier nicht das reichen? // Egal wieviele wir gefunden haben, wir geben nur eins aus. TEX := TEX + ',' + s[i]; Menge := 0; // end else TEX := TEX + s[i]; // LAST CHANGE inc(i); end; // END WHILE Memo2.text := TEX; Memo1.text := S; end; // Wenn ja, dann ließe sich das Problem eventuell so lösen:
Delphi-Quellcode:
Ansonsten eventuell:
s := '0,,25,01640X0174,01747,23,,,,47X014747';
s := AnsiReplaceText(s,'X01',' Typ A: '); s := AnsiReplaceText(s,'01',' Typ B: '); while Pos(',,',s) > 0 do begin s := AnsiReplaceText(s,',,',','); end;
Delphi-Quellcode:
s := '0,,25,01640X0174,01747,23,,,,47X014747';
s := StringReplace(s,'X01',' Typ A: ',[rfReplaceAll, rfIgnoreCase]); s := StringReplace(s,'01',' Typ B: ',[rfReplaceAll, rfIgnoreCase]); while Pos(',,',s) > 0 do begin s := StringReplace(s,',,',',',[rfReplaceAll]); end; |
AW: Zeichen in String ersetzen
Ich würde da auch auf jeden Fall über eine Zeichenersetzungs-procedure gehen und da alle möglichen Fälle abarbeiten. Ist doch viel übersichtlicher.
Falls es in D5 noch kein ReplaceStr, AnsiReplaceText, StringReplace oder dergleichen gab, schreib dir einfach eine eigene. z.B.
Delphi-Quellcode:
Und dann wie bereits vorgeschlagen:
function ReplaceString(StrOri, SuchStr, Repl:String):String;
var posi:integer; begin posi:=pos(SuchStr, StrOri); while posi > 0 do begin StrOri:=copy(StrOri,1,posi-1)+ repl + copy(StrOri, posi+length(SuchStr), length(StrOri)-posi-length(SuchStr)+1); posi:=pos(SuchStr, StrOri); end; result:=StrOri; end;
Delphi-Quellcode:
s := '0,,25,01640X0174,01747,23,,,,47X014747';
s := ReplaceString(s,'X01',' Typ A: '); s := ReplaceString(s,'01',' Typ B: '); while Pos(',,',s) > 0 do begin s := ReplaceString(s, ',,', ','); end; |
AW: Zeichen in String ersetzen
Nach meiner Kenntnis gibt es in Delphi 5 sehr wohl die StringReplace-Funktion.
|
AW: Zeichen in String ersetzen
Du läufst den kompletten String Zeichen für Zeichen durch und merkst Dir die Chars, an denen Du vorbeikommst.
Deine längste "Kennung" ist drei Zeichen lang (X01). Also brauchst Du nur drei Char-Variablen, die Du in dieser Schleife füllst/schiebst und prüfst, ob eine der Kennungen vorkommt. Die korrekten Zeichen und die korrigierten/ersetzten Zeichen schreibst Du in einen neuen (Ergebnis-)String. Oder Du schaust Dir mal an, wie ein Parser arbeitet ;-) |
AW: Zeichen in String ersetzen
Zitat:
Leider stoße ich auch immer wieder auf so etwas. Gibt es eine Übersicht, ab wann welche Funktion in Delphi verfügbar ist. Auf den Emba-Seiten steht die Version so weit ich weiß nicht. |
AW: Zeichen in String ersetzen
Was lernen wir daraus? Backup und nie mit den original Daten arbeiten. :?
|
AW: Zeichen in String ersetzen
Zitat:
Oder such nach FastCode, da solltest Du auch das eine oder andere finden. Gruß K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz