Replace substrings

       Hi!

I want to replace a ; in a string with space or some other character where the pattern is like aa;bb  or ab;ab.
That is the last 2 characters and the first 2 characters must be in the alphabet (non-number).

Regards,
  Tomas Helgi
LVL 26
Tomas Helgi JohannssonAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

heretoreadCommented:
StringReplace();

Look in delphi help for details.
0
DavidBirch2dotComCommented:
0
DavidBirch2dotComCommented:
function StringReplace ( const SourceString, OldPattern, NewPattern : string; Flags : TReplaceFlags ) : string;

The StringReplace function replaces the first or all occurences of a substring OldPattern in SourceString with NewPattern according to Flags settings.
 
The changed string is returned.
 
The Flags may be none, one, or both of these set values:
 
rfReplaceAll  : Change all occurrences
rfIgnoreCase  : Ignore case when searching


so in your case

before = 'AB;CD';

after = StringReplace ( before , ';', ' ', [rfReplaceAll] );

after will then be 'AB CD'

David

0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

KristaoCommented:
Lets make this more intereseting lets create our own StringReplace

function rep_str(s_in: string; rep: char; rep_w: char): string;
var
  i: integer;
begin
  i := 1;
  result := '';
  while i <> length(s_in) do
  begin
    if s_in[i] = rep then
    begin
      s_in[i] := rep_w;
    end;
    inc(i);
  end;
  result := s_in;
end;

in your case we just call function like this

ep_str('aa;bb', #59, #32);

and result will be 'aa bb'

regards,
Kristao
0
Tomas Helgi JohannssonAuthor Commented:
Ok so god so far.
But when the text could be varying from <a-z><a-z>;<a-z><a-z> then what ?

Regards,
  Tomas Helgi
0
KristaoCommented:
Where is the problem?

if you will give string "text" to function it will remove ; and replace with empty space, and it will not depend from length.
0
Tomas Helgi JohannssonAuthor Commented:
Well if you have text like

111;33;aaaa;bBBB;F1A;1200,0;00
or
133;afaaf;bQAA;fffA;F2A;1300,0;01

I only want to replace the ; between
aaaa;bBBB
or
afaaf;bQAA;fffA

That is two or more non-number characters on either side of a ; then I want to replace that ; with space.

Regards,
   Tomas Helgi
0
KristaoCommented:
function rep_str(s_in: string; rep: char; rep_w: char): string;
var
  i: integer;
  go: boolean;
  l: integer;
begin
  i := 1;
  result := '';
  while i <> length(s_in) do
  begin
    if s_in[i] = rep then
    begin
      go := true;

      if i <> 0 then
      begin
        if trystrtoint(s_in[i - 1], l) then go := false;
        if i <> 1 - 2 then
        begin
          if trystrtoint(s_in[i - 2], l) then go := false;
        end;
      end;

      if i <> length(s_in) then
      begin
        if trystrtoint(s_in[i + 1], l) then go := false;
        if i <> length(s_in) - 1 then
        begin
          if trystrtoint(s_in[i + 2], l) then go := false;
        end;
      end;

      if go then s_in[i] := rep_w;
    end;
    inc(i);
  end;
  result := s_in;
end;
0
KristaoCommented:
this will be more user friendly code:

function rep_str(s_in: string; rep: char; rep_w: char): string;
var
  i: integer;
  go: boolean;
  l: integer;
  k: integer;
begin
  i := 1;      //inicalize
  result := '';//inicalize
  while i <> length(s_in) do //check every char in string
  begin
    if s_in[i] = rep then //if we foun unwanted char
    begin
      go := true;  //inicalize

      for k := 1 to 2 do  //how many digits after you want to check now its 2
      begin
        if trystrtoint(s_in[i - k], l) then go := false; //n digits from unwanted char
        if trystrtoint(s_in[i + k], l) then go := false; //n digits from unwanted char
        if go = false then break;//break if found
      end;

      if go then s_in[i] := rep_w; //can we change unwanted char
    end;
    inc(i);
  end;
  result := s_in;
end;

regards,
Kristao
0
jimyXCommented:
Function ReplaceChar(Str:string;ChOld,ChNew:char):String;
var
  i:integer;
Begin
  result := '';
  for i := 1 to length(Str) do
    begin
      if (Str[i] = ChOld) then
        begin
          if (i >= 2) and (i <= length(Str) ) then
            begin
              if (Str[i-1] in ['a'..'z','A'..'Z']) and (Str[i-2] in ['a'..'z','A'..'Z']) and (Str[i+1] in ['a'..'z','A'..'Z']) and (Str[i+2] in ['a'..'z','A'..'Z']) then
                begin
                  Str[i] := ChNew;
                end;
            end
          else
            begin
              // if the semicolon is the first or second
              // element in your string
            end;
        end;
    end;
  result := Str;
end;

for example :

showmessage(ReplaceChar('133;afaaf;bQAA;fffA;F2A;1300,0;01',';',' '));
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
KristaoCommented:
Nice way  ['a'..'z','A'..'Z'] its better that trystrtoint(), but "for" cycle are slower than while in long activitys. My advise is to use while or repeat.
0
ZhaawZSoftware DeveloperCommented:
Kristao, "for" is faster than "while", at least if compiled with Delphi 6 (I believe that's because "for" loop has less to do with memory than "while" has; I'm not sure about this because I'm not an ASM spec - can't analyse how Delphi works with "for" and "while/repeat" loops). Here's small test:

var
  t : cardinal;
  n : integer;
begin
t := gettickcount;
{} // avg 10.0 secs
  for n := 0 to high(n) - 1 do ;
  for n := 0 to high(n) - 1 do ;
  for n := 0 to high(n) - 1 do ;
{}
{ // avg 12.7 secs
  n := 0; while n < high(n) do inc(n);
  n := 0; while n < high(n) do inc(n);
  n := 0; while n < high(n) do inc(n);
{}
{ // avg 12.7 secs
  n := 0; repeat inc(n) until n = high(n);
  n := 0; repeat inc(n) until n = high(n);
  n := 0; repeat inc(n) until n = high(n);
{}
caption := inttostr(gettickcount-t);
end;



Want to know what is slow? Using Delphi "string" - that's what is slow. And accessing single char in Delphi string also should be slow. And again - small test:

var
  t : cardinal;
  n : integer;
  s : string;
  p : pchar;
begin
t := gettickcount;
s := 'some strange string';
{} // avg 74.2 secs - fell asleep, aaargh
  for n := 0 to high(n) - 1 do s[1] := 'S';
  for n := 0 to high(n) - 1 do s[2] := 'O';
  for n := 0 to high(n) - 1 do s[3] := 'M';
  for n := 0 to high(n) - 1 do s[4] := 'E';
{}
{ // avg 16.9 secs
  p := @s[1];
  for n := 0 to high(n) - 1 do p[0] := 'S';
  for n := 0 to high(n) - 1 do p[1] := 'O';
  for n := 0 to high(n) - 1 do p[2] := 'M';
  for n := 0 to high(n) - 1 do p[3] := 'E';
{}
caption := inttostr(gettickcount-t);
end;
0
KristaoCommented:
for is slower than while and its true. I'm workt with server side applications and the most cycles was made on for. And performace on it was slower than when i remade it to while cycle , and that isn't 300 char long string what for cycles operated with there was 300 connections and lots of thouse dam strings :) . I took some time to study how for and while cycles look in ASM and there is a reason why for could be slower that while. FOR its self is loop and i we look in CPU what kind of operations are made there than there is an answer why.

ok test is good but in this kind of test you won't feelable results. Its better from beginig to train your self to use while cycles.
0
ZhaawZSoftware DeveloperCommented:
it's better to train yourself to use the right loops in right situations. i wouldn't advise to use while loop in all cases.
0
KristaoCommented:
why to use slower cycles? :)
0
ZhaawZSoftware DeveloperCommented:
I showed an example where FOR is faster than WHILE. It means that there ARE situations when FOR loops are faster.
Another thing - why do you use Delphi STRING, if it's *very* slow?
Another thing - "why to use slower cycles? :)"  <-- well, you should start using plain ASM in coding (with no pascal code, with no delphi objects etc)
0
KristaoCommented:
if use them incorectly then they will be slower. I will stay on my i know when for cycles are slow.
0
ZhaawZSoftware DeveloperCommented:
>> if use them incorectly
Well, correct work with pointers (i.e., pchar) will be much faster in all cases, afaik.

>> i know when for cycles are slow.
That's what I tried to say - when they ARE slow, use while/repeat. Otherwise there's no need to use while or repeat.
0
Tomas Helgi JohannssonAuthor Commented:
Thanks JimmyX

Regards,
  Tomas Helgi
0
jimyXCommented:
Any Time Tomas Helgi

                                      Jimmy
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.