Delphi递归函数替换字符串



我尝试递归替换找到的文本,但无法使其工作。这将只替换每个文本前的1个字符,但我想替换文本前的所有字符

//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.

我需要替换这个:"aaHaatextaaatextHHaatextHHaaaa"

最后的文本应该是这样的:"aaHtexttextHHtextHHaaaa"

试试这个

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')

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

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到String到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值进行替换。

谢谢你帮了我很多。由于支持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;

最新更新