![]() |
StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
Hallo #,
ich bekomme von Fremdprogrammen manchmal Text mit #10 als Trenner. Wie kann ich das Umbauen, so dass ich 1. #10 wird zu #13#10 2. #13#10 bleibt erhalten Nehm ich StringReplace wird aus #13#10 ein #13#13#10. Das will ich aber nicht !!! ;) Ich kann das nicht an irgendwelchen Sachen festmachen. Das scheint bei denen von der Tagesform abzuhängen ! Dass TStringList das umgehen kann, weiss ich. Heiko |
AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
Mit einer Regex die eben nur #10 matched wenn nicht #13 davor steht.
Oder Du ersetzt alle #13#10 durch #10 und dann in einem zweiten Schritt alle #10 durch #13#10. |
AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
Delphi-Quellcode:
oder einfach nur
S := StringReplace(S, #13#10, #10, [rfReplaceAll]); // Windows > Linux
S := StringReplace(S, #13, #10, [rfReplaceAll]); // Mac > Linux S := StringReplace(S, #10, sLineBreak, [rfReplaceAll]); // Linux > [s]Windows[/s] Systemstandard
Delphi-Quellcode:
.
with TStringList.Create do try Text:=S; S:=Text; finally Free end;
alle meckern über WITH, aber manchmal isses voll cool :oops: |
AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
Hallo,
auf die einfachsten Sachen kommt man nicht !! Danke |
AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
Die Sache mit der StringList ist aber recht langsam.
|
AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
StringReplace ist auch nicht gerade schnell.
Seit D2009 oder 2010 sollte es hierbei aber schneller sein, als ein StringReplace und hier gibt es 2-3 StringReplace. (hab's nicht gemessen, aber vom internen Arbeitsverhalten her, würde ich es so vermuten) |
AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
Hallo,
Speed spielt keine soo grosse Rolle. Heiko |
AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
Hallo hoika,
ich hatte vor einer Zeit das gleiche Problem und hatte zur Lösung eine kleine Routine geschrieben. Es hat etwas gedauert aber ich hab sie jetzt wiedergefunden. Die zweite Funktion ist "pure Pascal" und ist entsprechend langsamer. Um die Performance zu testen habe ich einen String mit der Länge 100 Mio komplett mit 'A's gefüllt, dann an 2 Mio zufälligen Positionen #10 bzw #13#10 eingestreut. Ergebnis : 175 ms bzw. 375 ms (zweite Funktion). Für einen Vergleich mit StringReplace(s,#10,#13#10,[rfReplaceAll]) habe ich einen String mit der Länge 1 Mio genommen und an 20000 Positionen #10 eigestreut. StringReplace braucht 39 s, die beiden anderen < 15 ms. Naja, kein ganz fairer Vergleich, weil StringReplace universell einsetzbar ist aber ich denke, daß die, die StringReplace geschrieben haben, sich die Sache etwas leicht gemacht haben.
Delphi-Quellcode:
FUNCTION EnsureCRLF(s:string):string;
FUNCTION Replace(dest,source:string):integer; asm push eax push ebx mov bx,$0A0D // BL=CR, BH=LF jmp @Entry @Char: mov [eax],cl add eax,1 @1: add edx,1 @Entry: mov cx,[edx] // 2 Chars aus Source cmp cx,bx je @CRLF cmp cl,bh je @LF test cl,cl jne @Char jmp @End @LF: mov [eax],bx add eax,2 jmp @1 @CRLF: mov [eax],bx add edx,2 add eax,2 jmp @Entry @End: pop ebx pop ecx sub eax,ecx end; //------------------------------------------------------------------------------ var len:integer; dest:string; begin if s='' then exit; SetLength(result,Length(s)*2); SetLength(result,Replace(result,s)); end;
Delphi-Quellcode:
FUNCTION xEnsureCRLF(var s:string):string;
FUNCTION Replace(var dest:string; const source:string):integer; var ps,pd,pdsave:PChar; begin ps:=@source[1]; pd:=@dest[1]; pdsave:=pd; repeat case ps^ of #10 : begin PWord(pd)^:=$0A0D; inc(PWord(pd)); inc(ps); end; #13 : if (ps+1)^=#10 then begin PWord(pd)^:=$0A0D; inc(PWord(pd)); inc(PWord(ps)); end else begin pd^:=#13; inc(pd); inc(ps); end; #0 : break; else begin pd^:=ps^; inc(pd); inc(ps); end; end; until false; result:=Integer(pd)-Integer(pdsave); end; //------------------------------------------------------------------------------ var len:integer; dest:string; begin if s='' then exit; SetLength(result,Length(s)*2); SetLength(result,Replace(result,s)); end; |
AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
@Amateurprofi:
Mach mal aus den String und PChar jeweils AnsiString und PAnsiChar, denn deine Funktionen sind nicht Unicodefähig. StringReplace ist nunmal sehr einfach programmiert. Es sucht das erste Vorkommen und verschiebt dann den kompletten nachvolgenden Stringanteil, danach sucht es das nächste Vorkommen und verschiebt ebenfalls wieder "alles" usw. Je länger der String und um so mehr Ersetzungen nötig sind um so mehr/öfters muß kopiert werden. (Seit der Integration des FastCodeProjekts in Delphi ... irgendwann um D2006 bis D2009 ... sind die Kopierfunktionen schneller, was StringReplace zumindestens etwas beschleunigt hat). Im himXML versteckt sich eine unaufällige Klasse (ich bin mir nicht sicher, aber ich hab das Gefühl diese auch schonmal einzeln hier irgendwo gepostet zu haben), über welche man Ersetzungen sammeln und dann mehrere solcher Ersetzungen etwas optimiert durchführen lassen kann (diese war mal wegen des StringReplace-Problems mal entstanden). Damit wäre auch soein StringReplace wie in PHP möglich, also mit mehereren unterschiedlichen Ersetzungen gleichzeitig. |
AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
Hallo,
ruhig Brauner :) Ich lese Daten aus Excel aus, da ist StringReplace noch der Überflieger ;) Danke an alle. Heiko |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05: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