在delphi中替换字符串中每个第三个字符的最佳方法

时间:2014-09-11 19:40:15

标签: string delphi delphi-5

在字符串中替换相同类型的每个第三个字符的最有效方法是什么?

我有一个这样的字符串:

str := 'c1'#9'c2'#9'c3'#9'c4'#9'c5'#9'c6'#9'

我想用#13#10替换每三个#9,以便我得到:

str1 := 'c1'#9'c2'#9'c3'#13#10'c4'#9'c5'#9'c6'#13#10' 

我会这样做:

i:=0;
newStr:='';
lastPos := Pos(str,#9);

while lastPos > 0 do begin
  if i mod 3 = 2 then begin
    newStr := newStr + Copy(str,1,lastPos-1) + #13#10;    
  end else begin
    newStr := newStr + Copy(str,1,lastPos);
  end;

  str := Copy(str,lastPos+1,MaxInt);
  i := i + 1;
  lastPos := Pos(str,#9);
end;

newStr := Copy(str,1,MaxInt);

但这就是很多复制品。是否有字符串操作功能来执行此操作?

3 个答案:

答案 0 :(得分:0)

我希望这个问题会被关闭,但只是为了好玩,这将是我的建议。

Function Replace(const Instr:String;Re:Char;const ReWith:String):String;
var
 i,o,cnt,l:Integer;
begin
  cnt:=0;
  o:=0;
  SetLength(Result,Length(Instr)*Length(ReWith));// just for security
  for I := 1 to Length(Instr) do
      begin
        if Instr[i]=Re then inc(cnt);
        if cnt=3 then
          begin
            for l := 1 to Length(ReWith) do
                begin
                 inc(o);
                 Result[o] := ReWith[l];
                end;
           cnt := 0;
          end
        else
          begin
            inc(o);
            Result[o] := Instr[i];
          end;
      end;
  SetLength(Result,o);
end;


procedure TForm3.Button1Click(Sender: TObject);
begin
 Edit2.Text := Replace(Edit1.Text,'A','xxx')
end;

答案 1 :(得分:0)

我认为所述问题与您提供的代码不符。每个第三个角色是#9吗?如果是这样,你想改变#13#10的第9个外观吗?

如果是这样,我会这样做:

function test(str: string): string;
var
  i, c, l: integer;
begin
  l := Length(str);
  SetLength(Result, l + l div 9);
  c := 1;
  for i := 1 to l do
  begin
    if (i mod 9 = 0) and (i > 0) then
    begin
      Result[c] := #13;
      Inc(c);
      Result[c] := #10;
    end
    else
      Result[c] := str[i];
    Inc(c);
  end;
end;

我实际上不知道这个功能是否表现良好。但鉴于约束条件不明确,我想是的。

如果#9字符的位置未知,则此解决方案根本不起作用。

编辑:正如大卫指出的那样,这与发布的原始代码几乎不相同。这似乎有效,但它需要在原始字符串上传递两次。问题是,要知道它是否更有效,我们需要更多地了解输入和上下文。

function OccurrencesOfChar(const S: string; const C: char): integer;
var
  i: integer;
begin
  result := 0;
  for i := 1 to Length(S) do
    if S[i] = C then
      inc(result);
end;

function Test(str: string): string;
var
  len, n, C, i: integer;
begin
  C := 1;
  len := Length(str);
  n := OccurrencesOfChar(str, #9);
  SetLength(result, len + n div 3);
  n := 1;
  for i := 1 to len do
  begin
    if str[i] = #9 then
    begin
      if n mod 3 = 0 then
      begin
        result[C] := #13;
        inc(C);
        result[C] := #10;
      end
      else
        result[C] := #9;
      Inc(n);
    end
    else
      result[C] := str[i];
    inc(C);
  end;
end;

答案 2 :(得分:0)

我可能会做这样的事情(在浏览器中编码)。它只需要一个字符串调整大小,并且应该减少数据移动。我在最后一次更换时退出,或者如果它不需要任何:

procedure ReplaceXChar(var aStringToReplace: string; const aIteration: 
    Integer; const aChar: Char; const aReplacement: string);
var
  replaceCount: Integer;
  cntr: Integer;
  outputCntr: Integer;
  lengthToReplace: Integer;
begin
  // Find the number to replace
  replaceCount := 0;
  for cntr := 1 to Length(aStringToReplace) do
  begin
    if aStringToReplace[cntr] = aChar then
      Inc(replaceCount);
  end;
  if replaceCount >= aIteration then
  begin
    // Now replace them
    lengthToReplace := Length(aReplacement);
    cntr := Length(aStringToReplace);
    SetLength(aStringToReplace, cntr + 
        (replaceCount div aIteration) * (lengthToReplace - 1));
    outputCntr := Length(aStringToReplace);
    repeat
      if aStringToReplace[cntr] = aChar then
      begin
        if (replaceCount mod aIteration) = 0 then
        begin
          Dec(outputCntr, lengthToReplace);
          Move(aReplacement[1], aStringToReplace[outputCntr+1], 
              lengthToReplace * SizeOf(Char));
        end
        else
        begin
          aStringToReplace[outputCntr] := aStringToReplace[cntr];
          Dec(outputCntr);
        end;
        Dec(replaceCount);
      end
      else
      begin
        aStringToReplace[outputCntr] := aStringToReplace[cntr];
        Dec(outputCntr);
      end;
      Dec(cntr);
    until replaceCount = 0;
  end;
end;

用法如下:

var
  myString: String;
begin
  myString := 'c1'#9'c2'#9'c3'#9'c4'#9'c5'#9'c6'#9;
  ReplaceXChar(myString, 3, #9, #13#10);
  ShowMessage(myString);
end;
相关问题