StringReplace alternatives to improve performance

前端 未结 8 755
温柔的废话
温柔的废话 2021-02-04 12:46

I am using StringReplace to replace > and < by the char itself in a generated XML like this:

StringReplace(xml.Text,\'>\',\'>\',[rfReplaceA         


        
8条回答
  •  我在风中等你
    2021-02-04 13:34

    it's work like charm so fast trust it

        Function NewStringReplace(const S, OldPattern, NewPattern: string;  Flags: TReplaceFlags): string;
    var
      OldPat,Srch: string; // Srch and Oldp can contain uppercase versions of S,OldPattern
      PatLength,NewPatLength,P,i,PatCount,PrevP: Integer;
      c,d: pchar;
    begin
      PatLength:=Length(OldPattern);
      if PatLength=0 then begin
        Result:=S;
        exit;
      end;
    
      if rfIgnoreCase in Flags then begin
        Srch:=AnsiUpperCase(S);
        OldPat:=AnsiUpperCase(OldPattern);
      end else begin
        Srch:=S;
        OldPat:=OldPattern;
      end;
    
      PatLength:=Length(OldPat);
      if Length(NewPattern)=PatLength then begin
        //Result length will not change
        Result:=S;
        P:=1;
        repeat
          P:=PosEx(OldPat,Srch,P);
          if P>0 then begin
            for i:=1 to PatLength do
              Result[P+i-1]:=NewPattern[i];
            if not (rfReplaceAll in Flags) then exit;
            inc(P,PatLength);
          end;
        until p=0;
      end else begin
        //Different pattern length -> Result length will change
        //To avoid creating a lot of temporary strings, we count how many
        //replacements we're going to make.
        P:=1; PatCount:=0;
        repeat
          P:=PosEx(OldPat,Srch,P);
          if P>0 then begin
            inc(P,PatLength);
            inc(PatCount);
            if not (rfReplaceAll in Flags) then break;
          end;
        until p=0;
        if PatCount=0 then begin
          Result:=S;
          exit;
        end;
        NewPatLength:=Length(NewPattern);
        SetLength(Result,Length(S)+PatCount*(NewPatLength-PatLength));
        P:=1; PrevP:=0;
        c:=pchar(Result); d:=pchar(S);
        repeat
          P:=PosEx(OldPat,Srch,P);
          if P>0 then begin
            for i:=PrevP+1 to P-1 do begin
              c^:=d^;
              inc(c); inc(d);
            end;
            for i:=1 to NewPatLength do begin
              c^:=NewPattern[i];
              inc(c);
            end;
            if not (rfReplaceAll in Flags) then exit;
            inc(P,PatLength);
            inc(d,PatLength);
            PrevP:=P-1;
          end else begin
            for i:=PrevP+1 to Length(S) do begin
              c^:=d^;
              inc(c); inc(d);
            end;
          end;
        until p=0;
      end;
    end;
    

提交回复
热议问题