Link to home
Start Free TrialLog in
Avatar of hidrau
hidrauFlag for Brazil

asked on

Help with function that can replace a part of a string sentence to another

Hello Guys,

I'd like a function where could replace a block of my text for another character.

See the example through this sentence:


"Is my sister  working with my father @at her mother's house@?"

as you can see, I have two AT (@) in my sentence, the simbol indicates the begining and the end block that must be replaced with another simbol, maybe the question mark "?", then, the sentence must be:

Is my sister working with my father ?? ?? ???????? ??????

As you can see, the space between the words must exist as the original string block.

Thanks
SOLUTION
Avatar of Kimputer
Kimputer

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
try

uses StrUtils;
....

function ReplaceText(const AText: string): string;
var
  Start, Stop: Integer;
  Repls: char;
  Temp, Filler: string;
begin
  Result := AText;
  Start := Pos('@', AText);
  if Start > 0 then
  begin
    Stop := PosEx('@', AText, Start+1);
    if (Stop > 0) and (Length(AText) > Stop) then
    begin
      Repls := AText[Stop+1];
      Temp := Copy(AText, Start, Stop-Start+2);
      for Start := 2 to Length(Temp) -2 do
        if Temp[Start] = '@' then
          Continue
        else if Temp[Start] > #32 then
          Filler := Filler + Repls
        else
          Filler := Filler + ' ';
      Result := AnsiReplaceText(Result, Temp, Filler);
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
const
  CTest = 'Is my sister  working with my father @at her mother''s house@?';
begin
  ShowMessage(ReplaceText(CTest));
end;

Open in new window

Avatar of hidrau

ASKER

Hello,

I forgot to tell that sometimes I have a sentence with two pair of @, for example:

That man is @working@ with my uncle at my mother's house and she is @cooking a delicious@ feijoada.

Then, the sentence must be:

That man is ????????? with my uncle at my mother's house and she is ??????? ? ??????? feijoada.

Maybe it would be great if the function could recognize how many pair of symbol I have in my sentence and it must replace the pairs.

thanks
Avatar of Kimputer
Kimputer

Again, if by accident you input uneven number of @ characters, the last will just disappear.


function TForm1.customreplace(original:String):String;
var i: integer;
begin

     customreplace := leftstr(original,pos('@', original)-1);

     for i := (pos('@', original) + 1) to (pos('@', original) + pos('@',rightstr(original,length(original) - pos('@',original)))-1) do
          begin
          if original[ i ] = ' '  then
              customreplace := customreplace + ' '
          else
              customreplace := customreplace + '?';
          end;

     customreplace := customreplace + rightstr(original,length(original) - (pos('@', original) + pos('@',rightstr(original,length(original) - pos('@',original)))));
     if pos('@', customreplace) > 0 then
        customreplace:=customreplace(customreplace);

end;

Open in new window

what version of Delphi are you using?  The answer will depend on whether you will use TPerlRegEx or TRegExReplace.

I would probably use the regular expression object to perform the replacement.  This pattern will give you the matches of the '@' delimited text
'@([^@]*)@'

Iterate the matches, using '[\w]' as your pattern, replacing with '?'

Then, use the Delphi StringReplace() function to replace all the '@' with '' to get rid of the delimiters.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
the utlimate statement can be reduced a little :

with data as   
  (select 'That man is @working@ with my uncle at my mother''s house and she is @cooking a delicious@ feijoada.' line from dual),
  substs as (
  select n, d3.line, 
    regexp_replace(nvl(lag(regexp_replace(d3.line, d4.line, d4.subst)) over (order by 1), d3.line), d4.line, d4.subst) subst,
    max(n) over (partition by d3.line) nn
  from data d3,
  ( select n, regexp_substr(line, '@{1}([^@]+)@{1}', 1, n, 'in') line, 
    regexp_replace(regexp_substr(line, '@{1}([^@]+)@{1}', 1, n, 'in', 1), '\w', '?', 1, 0, 'i') subst
  from data d1,
  (select level n from data d2 connect by level <=  regexp_count(line, '@{1}([^@]+)@{1}', 1, 'in')) x1) d4)
select line, subst 
from substs
where n = nn;

Open in new window


doing this on a table yourtable with a column line holding the text:

with data as   
  (select line from yourtable),
  substs as (
  select n, d3.line, 
    regexp_replace(nvl(lag(regexp_replace(d3.line, d4.line, d4.subst)) over (order by 1), d3.line), d4.line, d4.subst) subst,
    max(n) over (partition by d3.line) nn
  from data d3,
  ( select n, regexp_substr(line, '@{1}([^@]+)@{1}', 1, n, 'in') line, 
    regexp_replace(regexp_substr(line, '@{1}([^@]+)@{1}', 1, n, 'in', 1), '\w', '?', 1, 0, 'i') subst
  from data d1,
  (select level n from data d2 connect by level <=  regexp_count(line, '@{1}([^@]+)@{1}', 1, 'in')) x1) d4)
select line, subst 
from substs
where n = nn;

Open in new window

@Geert
I did not see anything in the question about a sql solution. Am I missing something? I was under the impression he was asking for a delphi function to do the parsing.
@Geert

Thanks for posting that.  I wasn't paying attention when Oracle introduced regular expression support back in 2003 (version 10g feature).  I learned something new.

===========
@hidrau

Where are your strings being stored? (file, database, WS, other)
PierreC
I wasn't aware that looking at a problem should only be done from 1 angle...

you can ride through a one-way street with more than only a car ...
walking is also possible, a bullet train might be a little over
@aikimark,
congrats on learning something
@Geert

Thank you.  And thanks, again, for posting it.

I'm probably doing an advanced regular expressions presentation at the upcoming Raleigh Code Camp, so any new knowledge in this area is welcome.  I'll give you the credit for alerting me and might post a copy of your SQL to illustrate another RegExp environment.
@Geert

Good point. Keeping an open mind and thinking out the box is always good when problem solving. My point was this question had nothing to do with databases or sql so in your analogy, your solution is the bullet train :)

Perhaps you should put in a request to add 'oracle database' to this questions topics so if someone is looking for that solution in future, they will find your answer, or maybe even a good idea for an article...
Avatar of hidrau

ASKER

Hello guys,

thanks for the help. Sorry for the delay. I was in another project and I had to stop to finish it first. Now I am returning to it.

Well, I keep all the sentences in access database.
Avatar of hidrau

ASKER

thanks