Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi StringReplace und doppelte Leerzeichen (https://www.delphipraxis.net/67152-stringreplace-und-doppelte-leerzeichen.html)

Pichel 10. Apr 2006 12:50


StringReplace und doppelte Leerzeichen
 
Hi...

Irgendwie ein absolut blödes Problem.

ich möchte in einem String keine doppelten Leerzeichen mehr haben.
Hierfür jetzt mal die Funktion StringReplace getestet.

Was bei beliebigen Zeichen funktioniert bringt mich hier fast zum Wahnsinn
Delphi-Quellcode:
s := StringReplace(s, ' ', ' ', [rfReplaceAll,rfIgnoreCase]);
funktioniert nicht und
Delphi-Quellcode:
s := StringReplace(s, #32#32, #32, [rfReplaceAll,rfIgnoreCase]);
auch nicht und
Delphi-Quellcode:
s := AnsiReplaceText(s, #32#32, #32);
bringt auch nicht den erwünschten Erfolg.

Any hint?

mirage228 10. Apr 2006 12:52

Re: StringReplace und doppelte Leerzeichen
 
Hi,

du könntest eventuell mit regulären Ausdrücken arbeiten.

Dann z.B. so einen Ausdruck wie (\s){2,} (oder ggf. direkt über die Angabe des Charakter-Codes, da \s ggf. auch andere Zeichen matched, soweit ich weiss) der nach mindestens 2 Leerzeichen matched suchen und das ganze Ergebnis mit einem Leerzeichen ersetzen.

mfG
mirage228

sakura 10. Apr 2006 12:59

Re: StringReplace und doppelte Leerzeichen
 
Zitat:

Zitat von Pichel
ich möchte in einem String keine doppelten Leerzeichen mehr haben.
Hierfür jetzt mal die Funktion StringReplace getestet.

Das funktioniert, wie auch bei anderen Zeichen mit StringReplace nicht. Wenn Du aus 'aa' einfach 'a' machen willst, dann wird aus dem String baac -> bac, und aus baaaac -> baac, ist bei Leerzeichen nicht anders.

Da musst Du Dir selbst eine kleine Funktion schreiben. Z.B.:
Delphi-Quellcode:
function RemoveDblSpaces(const InStr: string): string;
var
  LastIsSpace: Boolean;
  I, Cnt: Integer;
  Res: string;
begin
  SetLength(Res, Length(InStr));
  Cnt := 0;
  LastIsSpace := False;
  for I := 1 to Length(InStr) do
  begin
    if LastIsSpace and (InStr[I] = #32) then
      Continue;
    LastIsSpace := InStr[I] = #32;
    Inc(Cnt);
    Res[Cnt] := InStr[I];
  end;
  SetLength(Res, Cnt);
  Result := Res;
end;
...:cat:...

Jasocul 10. Apr 2006 13:40

Re: StringReplace und doppelte Leerzeichen
 
Alternative Lösung:
Delphi-Quellcode:
while Pos(' ', DeinString) > 0 do
  Delete(DeinString, Pos(' ', DeinString), 1);
oder
Delphi-Quellcode:
while Pos(' ', DeinString) > 0 do
  DeinString := StringReplace(DeinString, ' ', ' ', [rfReplaceAll]);
Kommen die doppelten Leerzeichen häufig in einem String vor, dann dürfte die zweite Variante schneller sein.

sakura 10. Apr 2006 13:42

Re: StringReplace und doppelte Leerzeichen
 
Zitat:

Zitat von Jasocul
Alternative Lösung:

Die Lösung funktioniert und ist schön kurz, aber hast Du Dir Gedanken über die Geschwindigkeit gemacht :shock:

...:cat:...

Jasocul 10. Apr 2006 13:45

Re: StringReplace und doppelte Leerzeichen
 
Zitat:

Zitat von sakura
Die Lösung funktioniert und ist schön kurz, aber hast Du Dir Gedanken über die Geschwindigkeit gemacht

Ich habe zumindest mit dieser Frage gerechnet. :zwinker:
Käme auf einen Versuch an. Vielleicht hat Pichel ja Lust, die Varianten zu vergleichen?

sakura 10. Apr 2006 13:59

Re: StringReplace und doppelte Leerzeichen
 
Zitat:

Zitat von Jasocul
Vielleicht hat Pichel ja Lust, die Varianten zu vergleichen?

Vielleicht, vielleicht aber auch nicht :mrgreen: Hier mal der TestCode (2 Labels auf einer Form)
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
const
  x: array[0..27] of string = (
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    #32, #32#32
  );
  TEST = 1000;
var
  Start, Stop, Freq: Int64;
  I: Integer;
  Source, Work, Dest: string;
begin
  Source := '';
  for I := 0 to 5000 do
    Source := Source + x[Random(Length(x))];

  QueryPerformanceFrequency(Freq);

  QueryPerformanceCounter(Start);
  for I := 1 to TEST do
  begin
    Work := Source;
    Dest := RemoveDblSpaces(Work);
  end;
  QueryPerformanceCounter(Stop);
  Label1.Caption := Format('%f ms', [(Stop - Start) / Freq * 1000]);

  QueryPerformanceCounter(Start);
  for I := 1 to TEST do
  begin
    Work := Source;
    while Pos(' ', Work) > 0 do
      Delete(Work, Pos(' ', Work), 1);
    Dest := Work;
  end;
  QueryPerformanceCounter(Stop);
  Label2.Caption := Format('%f ms', [(Stop - Start) / Freq * 1000]);
end;
Variante 1: ca. 42 ms
Variante 2: ca. 1567 ms

Vernichtendes Urteil gegen die while/Delete-Schleife ;)

...:cat:...

Pichel 10. Apr 2006 14:04

Re: StringReplace und doppelte Leerzeichen
 
Zitat:

Zitat von Jasocul
Käme auf einen Versuch an. Vielleicht hat Pichel ja Lust, die Varianten zu vergleichen?

Also meine "alte" Variante brauchte 2.654sek
Delphi-Quellcode:
while Pos(' ', DeinString) > 0 do
  Delete(DeinString, Pos(' ', DeinString), 1);
2.592sek
und
Delphi-Quellcode:
while Pos(' ', DeinString) > 0 do
  DeinString := StringReplace(DeinString, ' ', ' ', [rfReplaceAll]);
1.573sek

und das ganze bei einer Stringlänge von 77000 Zeichen, nicht so "pralle"

sakura 10. Apr 2006 14:07

Re: StringReplace und doppelte Leerzeichen
 
Zitat:

Zitat von Pichel
Also meine "alte" Variante brauchte 2.654sek
[...]
und 1.573sek

und das ganze bei einer Stringlänge von 77000 Zeichen, nicht so "pralle"

Nimm mein, die hat auf meinem PC nur 0,78 Millisekunden benötigt :mrgreen:

...:cat:...

Jasocul 10. Apr 2006 14:18

Re: StringReplace und doppelte Leerzeichen
 
Ok, OK, Ich gebe auf. War schon klar, dass das schneller ist, aber so eklatant? Das, ich 'abe nischt erwartet. :wink:


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:23 Uhr.
Seite 1 von 5  1 23     Letzte »    

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