Link to home
Start Free TrialLog in
Avatar of jennifere
jennifere

asked on

Parse string using Pos function

I am trying to parse a string but am having trouble with the Pos function.

Here is my string...

str := '1005 W. Busch Blvd. <BR>Suite 140 <BR>Tampa';

I need to pull just the city Tampa.  When I use the code below it pulls everything between the first <BR> and the end of the string.  Is there a way to read the string backwards and stop at the first <BR>?

City[i] := Trim(Copy(str, Pos(' <BR>',str) + 5, Length(str)));
Avatar of rbohac
rbohac

Try this out. The top two functions are something that I wrote and commonly use.


procedure RemoveFirstItem(Var Msg:String;Delimiter:String = '|');
begin
  Msg := copy(msg,pos(Delimiter,msg)+Length(Delimiter),Length(Msg));
end;

function GetNextItem(var Msg:String;Delimiter:String = '|'):String;
begin
  Result := copy(msg,1,pos(Delimiter,msg)-1);
  RemoveFirstItem(Msg,Delimiter);
end;

procedure TForm1.Button1Click(Sender: TObject);
var Text:String;
begin
Text := 'This<br>Is<br>My<br>Data<br>';

While Length(Text) > 0 do
  ShowMessage(GetNextItem(Text,'<br>'));
end;
A way to use that would be to pad an extra <br. after tampa and do the following...


str := '1005 W. Busch Blvd. <BR>Suite 140 <BR>Tampa<br>';
Address1 := GetNextItem(str,'<br>');
Address2 := GetNextItem(str,'<br>');
City := GetNextItem(str,'<br>');
Avatar of Russell Libby
Along the same lines, but in an OO approach:

usage would be like....

  with TStrParse.Create do
  begin
     Delimiter:='<BR>';
     Parse('1005 W. Busch Blvd. <BR>Suite 140 <BR>Tampa');
     ShowMessage(Items[2]);
     Free;
  end;


Regards,
Russell


------

type
  TStrParse         =  class(TObject)
  private
     // Private declarations
     FDelimiter:    String;
     FItems:        TStringList;
  protected
     // Protected declarations
     function       GetItem(Index: Integer): String;
     function       GetItemCount: Integer;
     procedure      SetItem(Index: Integer; Value: String);
  public
     // Public declarations
     constructor    Create;
     destructor     Destroy; override;
     procedure      Parse(Value: String);
     property       Delimiter: String read FDelimiter write FDelimiter;
     property       Items[Index: Integer]: String read GetItem write SetItem;
     property       ItemCount: Integer read GetItemCount;
  end;

function TStrParse.GetItem(Index: Integer): String;
begin
  result:=FItems[Index];
end;

function TStrParse.GetItemCount: Integer;
begin
  result:=FItems.Count;
end;

procedure TStrParse.SetItem(Index: Integer; Value: String);
begin
  FItems[Index]:=Value;
end;

constructor TStrParse.Create;
begin
  inherited Create;
  FDelimiter:='';
  FItems:=TStringList.Create;
end;

destructor TStrParse.Destroy;
begin
  FItems.Free;
  inherited Destroy;
end;

procedure TStrParse.Parse(Value: String);
var  Temp:       String;
     dwPos:      Integer;
begin
  FItems.Clear;
  if (FDelimiter = '') then
     FItems.Add(Value)
  else
  begin
     Temp:=Value;
     dwPos:=Pos(FDelimiter, Temp);
     while (dwPos > 0) do
     begin
        FItems.Add(Copy(Temp, 1, Pred(dwPos)));
        Delete(Temp, 1, Pred(dwPos)+Length(FDelimiter));
        dwPos:=Pos(FDelimiter, Temp);
     end;
     if (Temp > '') then FItems.Add(Temp);
  end;
end;

just like you want:

function  ReadBackward(S: string): string;
var
  I:      Integer;
  L:      Integer;
  T:      string;
  R:      string;
begin
  R := '';
  try
    L := Length(S);
    if (L>5) then
    begin
      for I := L downto 1 do
      begin
        if (S[I]='<') then
        begin
          T := Copy(S, I, 4);
          if (T='<BR>') then
          begin
            R := S;
            Delete(R, 1, I+3);
            Break;
          end;
        end;
      end;
    end;
  finally
    Result := R;
  end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  S:      string;
  T:      string;
begin
  S := '1005 W. Busch Blvd. <BR>Suite 140 <BR>Tampa';
  T := ReadBackward(S);
  ShowMessage(T);
end;

emil
or:

function  PullCity(S: string): string;
var
  I:      Integer;
  L:      Integer;
  R:      string;
begin
  R := '';
  try
    L := Length(S);
    if (L>4) then
    begin
      I := Pos('<BR>', S);
      if (I>0) then
      begin
        R := S;
        Delete(R, 1, I+3);
      end;
      I := Pos('<BR>', R);
      if (I>0) then
      begin
        Delete(R, 1, I+3);
      end;
    end;
  finally
    Result := Trim(R);
  end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var
  S:      string;
begin
  S := '1005 W. Busch Blvd. <BR>Suite 140 <BR>Tampa';
  ShowMessage(PullCity(S));
end;

emil
ASKER CERTIFIED SOLUTION
Avatar of scrapdog
scrapdog
Flag of United States of America image

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 following is a function I wrote to handle parsing a delimited string - in your example, you would call it as:

City := ParsePos( str, '<BR>', 3 );

The function returns the value following the delimeter (so you pass three to get the third item in the list)

function ParsePos(sString, sDelim: string; iPos: integer): string;
var
   sResult : string;
   i : integer;
begin
   { If delimiter is not specified, return the string }
   if ( Pos( sDelim, sString ) < 1 ) then
      Result := sString
   else
   begin
      Result := sString;
      for i := 1 to iPos - 1 do
         Result := Copy( sResult, Pos( sDelim, sResult ) + Length( sDelim ), Length( sResult ) );

      if ( Pos( sDelim, Result ) > 0 ) then
         Result := Copy( Result, 1, Pos( sDelim, Result ) - 1 );
   end;
end;