Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I tried replace found text recursively but i cant get it working. This will replace only 1 ´a´ char before each ´text´ but i want replace all ´a´ characters before text

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

I need replace this: 'aaHaaatextaaaatextHHaatextHHaaaa'

final text should looks like this: 'aaHtexttextHHtextHHaaaa'

share|improve this question
 
Read the documentation for Pos, the first argument is the string you're searching for. Then put a breakpoint on the same line and examine what does Result hold when the breakpoint is hit. –  Sertac Akyuz Jul 3 at 17:57
 
You should use a for with an if inside and you will solve your problem easily ;) –  DK64 Jul 3 at 17:57
1  
What is XMLString? Copy and paste your real code. –  Rob Kennedy Jul 3 at 18:52
 
When you say you "can't get it working," what does that mean? What did you do to try to get it working, and how did your efforts fail? Stack Overflow is not the place to ask people to debug your code for you. Debugging is your job. What problem are you having in debugging this code yourself? Identify that problem, and then ask here how to overcome it. –  Rob Kennedy Jul 3 at 18:56

3 Answers

Try this

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

and use like so

OneLine('aaHaaatextaaaatextHHaatextHHaaaa','atext','text')
share|improve this answer
 
Thanks but this is not recursive function. I already tried while loop and it worked, but i try to get working function which will call itself = recursive fuction –  Nafalem Jul 3 at 18:37
2  
Why you need a recursive function? –  RRUZ Jul 3 at 18:47
 
Because... why not :ˇ) –  Nafalem Jul 3 at 18:49
6  
Because it is not an efficient solution for your problem. –  Remy Lebeau Jul 3 at 19:47
 
@Nafalem - so turn a loop into recursive function, what the problem ? –  Arioch 'The Jul 4 at 10:51

Your recursive logic is wrong, not to mention more complex then it needs to be. Try this instead:

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;

Also, you do realize that StringReplace() does not support WideString, don't you? So you are doing a lot of unnecessary WideString-to-String-to-WideString data conversions at each step. Change OneLine() to take and return a String instead so it can continue using StringReplace() and the WideString conversions are only performed at the initial call site:

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

Or else re-implement OneLine() to stop using StringReplace() altogether and instead manually search-and-replace using WideString values exclusively.

share|improve this answer

Thanks this helped me alot. I used widestring function because of unicode support, but it seems also string functions work with UTF-8 (probably it depends on version of Delphi, i used Turbo delhpi 7). I used it to format a strings in UTF-8-encoded xml file.

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;
share|improve this answer
 
Pain awaits. Use real XML library. –  David Heffernan Jul 6 at 6:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.