我尝试递归替换找到的文本,但我无法让它工作。 这将在每个'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'
答案 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;