// Getestet mit D4 unter WinME

// Als ich mit der Funktion StringReplace einen String mit 369.204 Zeichen
// bearbeitete, musste ich feststellen, dass mein Computer dazu rund
// 2 Minuten brauchte. Mit dem
ReplaceDialog dauerte es immer noch 4,4 Sekunden.
// Deshalb habe ich die folgende Funktion geschrieben, welche das Ganze in
// 0,5 Sekunden erledigte und noch zwei weitere Möglichkeiten bietet:
// 1. Man kann angeben, wieviele Mal eine Zeichenfolge ersetzt werden soll
//    und kann so beispielsweise nur die ersten drei Vorkommen ersetzen.
//    Dazu gibt man für
Number den entsprechenden Wert an. Ist dieser Wert
//    kleiner als Null
(oder größer als die Anzahl der Fundstellen) wird
//    alles Gefundene ersetzt.
// 2. Man kann angeben, dass das neue Wort in der Schreibweise an das alte
//    Wort angepasst wird.

// Allerdings sei nicht verschwiegen, dass bei sehr seltenem Vorkommen
// des zu ersetzenden Begriffes oder bei langen Worten,
Stringreplace
// die Nase vorn hat!


// P.S.
// Inzwischen habe ich einen schnelleren Rechner. Um im oben genannten
// String alle "e" gegen "a" auszutauschen benötigte:
//
Stringreplace 38,74 Sekunden
//
Myreplace      0,17 Sekunden
// Um alle "x" gegen "a" auszutauschen benötigte:
//
Stringreplace 1,40 Sekunden
//
Myreplace     0,25 Sekunden
// Um alle "Ursprung" gegen "Basis" auszutauschen benötigte:
//
Stringreplace 0,06 Sekunden
//
Myreplace     0,20 Sekunden
 

type 
  TMyReplaceType = set of (IgnoreCase, SameSpelling); 
 
function MyReplace(const s, OldPattern, NewPattern: string; Number: integer; 
  Way: TMyReplaceType): string; 
var 
  mq, mz: TStringStream; 
  x, z, lga, lgn, lgs: integer; 
  c, v: string; 
  procedure withcomparison; 
  var i, j: integer; 
  begin 
    if lga <= lgn then begin 
      j := lgn - lga; 
      for i := 1 to lga do 
        if isCharUpper(c[i]) then 
          charupperbuff(@mz.datastring[i + x + z * j], 1) 
        else charlowerbuff(@mz.datastring[i + x + z * j], 1); 
      if lgn > lga then begin 
        if isCharUpper(c[lga]) then 
          charupperbuff(@mz.datastring[x + lga + z * j + 1], j) else
          charlowerbuff(@mz.datastring[x + lga + z * j + 1], j);
      end; 
    end else begin 
      j := lga - lgn; 
      for i := 1 to lgn do 
        if isCharUpper(c[i]) then 
          charupperbuff(@mz.datastring[i + x - z * j], 1) 
        else charlowerbuff(@mz.datastring[i + x - z * j], 1); 
    end; 
  end; 
begin 
  lga := length(OldPattern); 
  if (lga > 0) then begin 
    lgn := length(NewPattern); 
    z := 0; 
    v := ansilowercase(OldPattern); 
    lgs := length(s); 
    setlength(c, lga); 
    mq := TStringStream.create(s); 
    mz := TStringStream.create(result); 
    try 
      x := 0; 
      while x <= mq.size - lga do begin 
        mq.position := x; 
        mq.readbuffer(c[1], lga); 
        if (c = OldPattern) or ((IgnoreCase in Way) and (ansilowercase(c) = v)) 
          then begin 
          if lgn > 0 then begin 
            mz.writebuffer(NewPattern[1], lgn); 
            if SameSpelling in Way then withcomparison; 
          end; 
          inc(z); 
          inc(x, lga); 
          if z = Number then break; 
        end else begin 
          mz.writebuffer(c[1], 1); 
          inc(x); 
        end; 
      end; 
      mq.position := x; 
      if x < lgs then 
        mz.copyfrom(mq, lgs - x); 
      result := mz.datastring; 
    finally 
      mz.free; 
      mq.free; 
    end; 
  end else result := s; 
end; 
 
// Beispielaufruf: Vergleich StringReplace mit MyReplace 
procedure TFormx.BitBtn2Click(Sender: TObject); 
begin 
  richedit1.lines.add(MyReplace('Ich bin im Nebenhaus', 'Haus', 'GEBÄUDE', -1, 
    [SameSpelling, Ignorecase])); 
  richedit1.lines.add(StringReplace('Ich bin im Nebenhaus', 'Haus', 'GEBÄUDE', 
    [rfIgnorecase, rfReplaceall])); 
end; 

Ergebnis Myreplace:     Ich bin im Nebengebäude
Ergebnis StringReplace: Ich bin im NebenGEBÄUDE



Zugriffe seit 6.9.2001 auf Delphi-Ecke