# Lazarus

## Free Pascal => Beginners => Topic started by: JLWest on November 13, 2019, 05:23:46 am

Title: String Function Question
Post by: JLWest on November 13, 2019, 05:23:46 am
Is there a string function to replace a character in a string with something else? Trying to make the following work but it doesn't make the changes in Bit1;

Var
Bit1 : String = '';

Bit1 := ReplaceWhatInWhatWithWahat(',',TestString,'|');

Code: Pascal  [Select][+][-]
1. function ReplaceWhatInWhatWithWhat(Const ACHAR : Char; Const ASTRING : String; Const  BCHAR : Char) : String;
2.   Var  i    :  Integer = -1;
3.    IDXA     : Integer = -1;
4.    IDXB     : Integer = -1;
5.    IDXC     : Integer = -1;
6.    Line     :  String = '';
7.    CChar    :  Char;
8.   begin
9.   Line := ASTRING;
10.   Line := Trim(Line);
11.   IDXA := Ord(ACHAR);
12.   IDXB := Ord(ACHAR);
13.   for i := 1 to Length(Line) do  begin
14.        CChar := Line[i];
15.        IDXC := Ord(CChar);
16.        if IDXC = IDXA then begin Line[1] := BCHAR; end;
17.    end;
18.  Result := Line;
19. end;
Title: Re: String Function Question
Post by: 440bx on November 13, 2019, 06:13:06 am
Maybe the function "StringReplace" is what you're looking for.

Check out the documentation page for it at https://www.freepascal.org/docs-html/rtl/sysutils/stringreplace.html

HTH.
Title: Re: String Function Question
Post by: fred on November 13, 2019, 08:20:49 am
Code: Pascal  [Select][+][-]
1. if IDXC = IDXA then begin Line[1] := BCHAR; end;
Are you sure that you need index 1 every time?  8-)
Title: Re: String Function Question
Post by: JLWest on November 13, 2019, 01:59:38 pm
I thin that's the problem., should be i not 1.

Thanks.
Title: Re: String Function Question
Post by: Thaddy on November 13, 2019, 03:36:30 pm
It is built in:
Code: Pascal  [Select][+][-]
1. {\$mode objfpc}{\$H+}
2. uses
3.   sysutils;
4. var s:string = 'besb me ';
5. begin
6.   writeln(s.Replace('b','t',[rfReplaceAll]));
7. end.

You can also use https://www.freepascal.org/docs-html/rtl/sysutils/stringreplace.html which does the same.

Anyway: the algorithm is easy:
Code: Pascal  [Select][+][-]
1. {\$mode delphi}{\$H+}
2. uses
3.   sysutils;
4. var
5.    s1:string = 'cesc me';
6.    i:integer;
7. begin
8.   for i:= 1 to length(s1) do
9.     if s1[i] ='c' then s1[i] := 't';
10.   writeln(s1);
11. end.
Note that the latter only works for single char replacements, but it will replace all occurrences..

(I wonder where your original idea/code comes from? It is definitely not yours...but from somewhere else? Trying to translate?)

Title: Re: String Function Question
Post by: JLWest on November 24, 2019, 07:23:32 am

I tried to adapt  'function Count(What, InWhat: String): Integer; ' to what I needed.

I got my function working by changing the 1 to i.

However I think the
s.Replace('b','t',[rfReplaceAll])); is very elegant and I need to change to that.

Thanks.
Title: Re: String Function Question
Post by: Birger52 on December 05, 2019, 05:50:40 pm
Just a not to StringReplace.
Had a situation with importing files, where someone went overboard with the enter button, to create new lines, so there could be more than for #13's in a row...
[rfReplaceAll] is not recurive,
so StringReplace(aString, #13#13, #13, [rfReplaceAll])
will only replace from the original - not with the charaters replaced.
A string with #13#13#13# or 13#13#13#13 would contain #13#13 after replacement
So constructions like
while Pos(#13#13, aString) do aString := StringReplace(aString, #13#13, #13, [rfReplaceAll])
may be needed
Title: Re: String Function Question
Post by: lucamar on December 05, 2019, 06:30:54 pm
Just a not to StringReplace.

For future generations :) , you meant "Just a note ...", didn't you?

It's a good note: StringReplace() does a single pass, jumping over recently replaced strings so it must be called in a while (or similar) loop to replace recursively.
Title: Re: String Function Question
Post by: Zvoni on December 06, 2019, 12:34:06 pm
There is quite a "nasty" trick to solve the problem of consecutive characters you'd like to trim down:
Split the String!
https://www.freepascal.org/docs-html/rtl/sysutils/tstringhelper.split.html
and use Option "ExcludeEmpty"
https://www.freepascal.org/docs-html/rtl/sysutils/tstringsplitoptions.html
Then join the Array back together

Another way would be to run a string from its end to its start (maybe using a pointer),
first comparing position i with searched character,
if yes then compare with position i+1, if equal copy ("move") pointer i+1 to i