Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert (https://www.delphipraxis.net/161740-stringreplace-10-13-10-aber-nur-wenn-nicht-schon-13-10-existiert.html)

hoika 18. Jul 2011 16:10

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

Phoenix 18. Jul 2011 16:13

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.

himitsu 18. Jul 2011 16:16

AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
 
Delphi-Quellcode:
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
oder einfach nur
Delphi-Quellcode:
with TStringList.Create do try Text:=S; S:=Text; finally Free end;
.

alle meckern über WITH, aber manchmal isses voll cool :oops:

hoika 18. Jul 2011 16:30

AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
 
Hallo,

auf die einfachsten Sachen kommt man nicht !!


Danke

Phoenix 18. Jul 2011 17:06

AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
 
Die Sache mit der StringList ist aber recht langsam.

himitsu 18. Jul 2011 17:21

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)

hoika 18. Jul 2011 18:53

AW: StringReplace #10 -> #13#10, aber nur wenn nicht schon #13#10 existiert
 
Hallo,

Speed spielt keine soo grosse Rolle.


Heiko

Amateurprofi 18. Jul 2011 23:44

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;

himitsu 19. Jul 2011 08:13

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.

hoika 19. Jul 2011 08:23

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 13:10 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz