We help IT Professionals succeed at work.

"pos" command with user defined starting point?

mathes
mathes asked
on
690 Views
Last Modified: 2010-05-18
Hi experts,

I think we all know the "pos" command.

It tells us the first occurance of a character in a string.
Unfortunately, "pos" parses a string always from the first character
to its last character.

But I need a source, where I can determine myself at which starting point
the parsing process should begin.

To clarify what I mean, I give you this example:

teststring:="this is a # test string # for the # experts';

Now I want to search for the blank character.
The "normal "pos" command would bring the result "6", because the
first blank in this string is the blank between "this" and "is".

But I need a source code who tells me the first occurence of a blank AFTER
the "#" character.

I want a routine, which in this case brings the result "11", the blank between
"#" and "test".

Have you an idea, how this could be accomplished?

With kind regards

Mathes
Comment
Watch Question

Top Expert 2004

Commented:
hi mathes,

why not use

MyPos := pos('# ',teststring)+1;

meikl
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
Hi experts,

can you please explain to me, what this FindStr exactly does? The string to be scanned is always the same,
so why do I see different results in your examples?

      FindStr('test','blabla test blabla test blabla',1,maxInt) -> 8
      FindStr('test','blabla test blabla test blabla',9,maxInt) -> 20
      FindStr('test','blabla test blabla test blabla',maxInt,1) -> 20
      FindStr('test','blabla test blabla test blabla',19,1) -> 8


The idea of Kretzmar indeed works only in a specific situation.

What I actually want to do is this.

I want to change all occurrencies of "@teststring" to the result "@tes".


Unfortunately I don't know if the user wrote someting like

"@teststri" or "@teststr" or "@teststrin" or "@tes"

So I must be able to handle different lenghths of my master string.

Or to say it in other words

I want to change all occurencies of "@tes* " to "@tes "

There are 2 details which I know for sure:

a) The string to be scannned starts with an "@"
b) after the string to be scannend there will follow a blank.

How would you solve this problem?

With kind regards

Mathes

Commented:
Hi Mathes,

FindStr is exactly like PosStr. But PosStr searches always from the first character to the last, while my FindStr function searches from the "fromPos" character to the "toPos" character.

Look again at these examples. The strings are the same, but the "fromPos" and "toPos" parameters change.

- FindStr('test','blabla test blabla test blabla',1,maxInt) -> 8
Looks from the first until the last character. So it returns "8", just as PosStr would do.

- FindStr('test','blabla test blabla test blabla',9,maxInt) -> 20
Begins with the search at character number 9 until the last character. So it doesn't find the "test" at position 8, but the second "test" at position 20.

- FindStr('test','blabla test blabla test blabla',maxInt,1) -> 20
Looks from behind backwards. So it returns the second "test", not the first one.

- FindStr('test','blabla test blabla test blabla',19,1) -> 8
Looks from the 19th character backwards. So it doesn't find the "test" at position 20, but the other one at position 8.

Everything clear now?

Ok, now your problem. I didn't test this code, but I guess it should work:

procedure MathesReplaceProblem(var str : string);
var i1,i2 : integer;
begin
  i1:=FindStr('@tes',str,1,maxInt);
  while i1>0 do begin
    i2:=FindStr(' ',str,i1+4,maxInt);
    if i2=0 then begin
      Delete(str,i1+4,maxInt);
      break;
    end;
    Delete(str,i1+4,i2-i1-4);
    i1:=FindStr('@tes',str,i1+4,maxInt);
  end;
end;

Regards, Madshi.
Top Expert 2004

Commented:
hi mathes,

of course my comment was just a joke

a function (parameters : MasterString, Begin of the word to search, replacestring, Enddelimiter of your word to search)

function replace_it_with_delimiter(SourceS, OldS, NewS, DelS : String) : String;
var
  P,P2 : Integer;
  WordS,
  STmp, STmp2 : String;
begin
  STmp2 := '';
  STmp := SourceS;
  P := pos(OldS,STmp);
  while p <> 0 do
  begin
    STmp2 := STmp2 + copy(STmp,1,p-1)+NewS;
    delete(STmp,1,p+Length(OldS)-1);
    P2 := pos(DelS,STmp);
    delete(STmp,1,p2-1);
    P := pos(OldS,STmp);
  end;
  STmp2 := STmp2 + STmp;
  result := STmp2;
end;

call example

procedure TForm1.Button1Click(Sender: TObject);
begin
  memo1.text := replace_it_with_delimiter(memo1.text,edit1.text,edit2.text,' ');
end;

meikl

Author

Commented:
Dear Mashdi,

thank you very much for your advice. I understand now hw I can use these string routines
and your example sorce code works very well, too. And it is extremly FAST! WOW !!!

With kind regards

Mathes

Author

Commented:
Dear Mashdi,

thank you very much for your advice. I understand now hw I can use these string routines
and your example sorce code works very well, too. And it is extremly FAST! WOW !!!

With kind regards

Mathes

Commented:
Mathes, yes, it's as fast as it can be (I think). I'm using this function very often in my programs, so I decided to work out a fast solution...   :-)

meikl, I didn't test your code, probably it would work, but it's quite slow, because you make Delphi reallocating the strings very often. My function does the same work much faster...

I really don't know why Inprise has not implemented a function like FindStr yet. I think it's a quite important one!

Regards, Madshi.
Top Expert 2004

Commented:
hi madshi,

of course, your assemblercode is very much faster, than my little delphi-code. It can be optimized, but it will be never become the fastest solution.

Happy new year

meikl

Author

Commented:
Dear meikl,

thank you for your comment. I wanted to test your source code
but I have some problems with it.

My testprogram consists of a form with a command button,
a memo and 2 edit controls.

But now when I click on the command button
it happens nothing.


Can you please tell me what I am doing wong here?

With kind regards

Mathes


unit meikl_test;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
 
 function replace_it_with_delimiter(SourceS, OldS, NewS, DelS : String) : String;
var
  Form1: TForm1;

implementation

function replace_it_with_delimiter(SourceS, OldS, NewS, DelS : String) : String;
      var
        P,P2 : Integer;
        WordS,
        STmp, STmp2 : String;
      begin
        STmp2 := '';
        STmp := SourceS;
        P := pos(OldS,STmp);
        while p <> 0 do
        begin
          STmp2 := STmp2 + copy(STmp,1,p-1)+NewS;
          delete(STmp,1,p+Length(OldS)-1);
          P2 := pos(DelS,STmp);
          delete(STmp,1,p2-1);
          P := pos(OldS,STmp);
        end;
        STmp2 := STmp2 + STmp;
        result := STmp2;
      end;
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
 memo1.text := replace_it_with_delimiter(memo1.text,edit1.text,edit2.text,' ');
end;

end.

Top Expert 2004

Commented:
hello mathes,

here is my unit, where i tested it.

i filled the memo with

Hello Tello Hello Hello Tello Hello Hello Tello Hello Hello Tello Hello Hello Tello Hello

edit1 with Hel
edit2 with Hallo

when i press the button each Hello becomes Hallo

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function replace_it_with_delimiter(SourceS, OldS, NewS, DelS : String) : String;
var
  P,P2 : Integer;
  WordS,
  STmp, STmp2 : String;
begin
  STmp2 := '';
  STmp := SourceS;
  P := pos(OldS,STmp);
  while p <> 0 do
  begin
    STmp2 := STmp2 + copy(STmp,1,p-1)+NewS;
    delete(STmp,1,p+Length(OldS)-1);
    P2 := pos(DelS,STmp);
    delete(STmp,1,p2-1);
    P := pos(OldS,STmp);
  end;
  STmp2 := STmp2 + STmp;
  result := STmp2;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  memo1.text := replace_it_with_delimiter(memo1.text,edit1.text,edit2.text,' ');
end;

end.

It works also with other entrys, and it should also work in your coding. I've copied your code and it works also. No Errors. Check your inputs.

meikl


Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.