Delphi递归函数替换字符串

时间:2013-07-03 17:42:20

标签: delphi function recursion replace

我尝试递归替换找到的文本,但我无法让它工作。 这将在每个'text'之前仅替换1'a'字符,但我想在文本之前替换所有'a'字符

//Declared recursive function
function OneLine(s:WideString):WideString;
begin
s:=StringReplace(s,'atext', 'text', [rfReplaceAll]);

if (Pos(Result,'atext')>0) then
 begin
 //XMLstring:=Result;
 s:=OneLine(XMLstring);
 end
 else
 begin
 Result:=XMLstring;
 end;
end;

//--Here begins program
Var
t:string
Begin

//exaple of text 
//we need replace all 'a' before 'text' only
t:='aaHaaatextaaaatextHHaatextHHaaaa';

//call custom recursive function
t:=OneLine(t); 

ShowMessage(t);

End.

我需要替换它:'aaHaaatextaaaatextHHaatextHHaaaa'

最终文本应如下所示:'aaHtexttextHHtextHHaaaa'

3 个答案:

答案 0 :(得分:4)

试试这个

function OneLine(const S, OldPattern, NewPattern: string):string;
begin
 Result:=s;
 repeat
  Result:=StringReplace(Result, OldPattern, NewPattern, [rfReplaceAll]);
 until Pos(OldPattern, Result)=0;
end;

并使用如此

OneLine('aaHaaatextaaaatextHHaatextHHaaaa','atext','text')

答案 1 :(得分:2)

你的递归逻辑是错误的,更不用说它需要更复杂了。试试这个:

function OneLine(const s: WideString): WideString;
begin
  if Pos(WideString('atext'), s) > 0 then
    Result := OneLine(StringReplace(s, 'atext', 'text', [rfReplaceAll]))
  else
    Result := s;
end;

此外,您确实意识到StringReplace()不支持WideString,不是吗?因此,您在每一步都要进行大量不必要的WideString-to-String-to-WideString数据转换。更改OneLine()以获取并返回String,以便它可以继续使用StringReplace(),并且WideString次转化仅在初始呼叫网站上执行:

function OneLine(const s: String): String;
begin
  if Pos('atext', s) > 0 then
    Result := OneLine(StringReplace(s, 'atext', 'text', [rfReplaceAll]))
  else
    Result := s;
end;

或者重新实施OneLine()以完全停止使用StringReplace(),而是仅使用WideString值手动搜索和替换。

答案 2 :(得分:0)

谢谢这帮了我很多。我使用了宽带函数,因为unicode支持,但似乎字符串函数也适用于UTF-8(可能它取决于Delphi的版本,我使用的是Turbo delhpi 7)。 我用它来格式化UTF-8编码的xml文件中的字符串。

function OneLineCDATA(const s: String): String;
begin
  if Pos(#9+'<![CDATA[', s) > 0 then
    Result := OneLineCDATA(StringReplace(s, #9+'<![CDATA[', '<![CDATA[', [rfReplaceAll]))
  else
    if Pos(#13+#10+'<![CDATA[', s) > 0 then
      Result := OneLineCDATA(StringReplace(s, #13+#10+'<![CDATA[', '<![CDATA[', [rfReplaceAll]))
     else
        if Pos(']]>'+#13+#10, s) > 0 then
          Result := OneLineCDATA(StringReplace(s, ']]>'+#13+#10, ']]>', [rfReplaceAll]))
        else
          if Pos(']]>'+#9, s) > 0 then
            Result := OneLineCDATA(StringReplace(s, ']]>'+#9, ']]>', [rfReplaceAll]))
           else
             Result := s;

end;