Solved

Can i revert the PosX function?

Posted on 2009-05-15
14
844 Views
Last Modified: 2012-05-07
I need to search backwards in a string. Cant find any string utils to do this. I can probably code some stuff that does this myself - but is there no function/procedure for this?
0
Comment
Question by:Sunsales
  • 3
  • 2
  • 2
  • +4
14 Comments
 
LVL 13

Expert Comment

by:rfwoolf
ID: 24400472
Hmmm i guess you could reverse your string and your searchterm, and then use posex. I'll keep thinking
0
 
LVL 13

Expert Comment

by:rfwoolf
ID: 24400482
How about
function LastDelimiter(const Delimiters, S: string): integer;
description
Returns the index of the last occurence in a string of the characters cpecified.
0
 
LVL 6

Expert Comment

by:JosephGlosz
ID: 24400613
Come on, rf, you only thought for three more minutes?

LastDelimiter won't work. You misunderstand how the parameter Delimiters functions. It's a string in which you specify a SET of one-character delimiters. It's not declared as a real set, but it is a set nonetheless.

so for example, you can call  i := LastDelimiter('abc,.',S);  

if S is '123a567c' then i will be 8, which is the last occurence of one of the Delimiters.

the function LastDelimiter does NOT search for the last occurence of the string Delimiters.

So, you can't use it to search for the last occurence of 'joe' for example. You can only use it to search for the last occurence of a single character. And if you are gonna do that, you may as well just do it yourself with a simple for loop.

0
 

Author Comment

by:Sunsales
ID: 24400738
I was thinking of revers the string - but it can be quite large - so i would prefer another solution because of time efficiency.
0
 
LVL 6

Expert Comment

by:JosephGlosz
ID: 24400807
well, I found this function, but it is remarkably inefficient. Delphi's POS function is written in assembler and seems very efficient.

function LastPos(SubStr, S: string): Integer;
var
  Len, X: integer;
begin
  Len := length(SubStr);
  X := length(S) - Len + 1;
  result := 0;
  while (X > 0) and (result = 0) do
  begin
    if copy(S, X, Len) = SubStr then
      result := X;
    dec(X);
  end;
end;

maybe someone can improve upon this?

0
 
LVL 13

Accepted Solution

by:
ThievingSix earned 100 total points
ID: 24400856
Something simple, not sure of the speed but you can let me know. If speed is too slow I can rework with asm.
function ReverseSearch(const SubString, S: String; Offset: Integer = 1): Integer;

var

  pS,

  pResult : PChar;

  ptrS,

  ptrResult : Pointer;

begin

  pS := PChar(S);

  ptrS := Pointer(pS);

  pResult := SearchBuf(pS,Length(S),Length(S) - Offset,Length(S),SubString,[]);

  ptrResult := Pointer(pResult);

  Result := Integer(ptrResult) - Integer(ptrS);

end;

Open in new window

0
 
LVL 13

Assisted Solution

by:ThievingSix
ThievingSix earned 100 total points
ID: 24400859
A little cleaner:
function ReverseSearch(const SubString, S: String; Offset: Integer = 1): Integer;

var

  pS : PChar;

begin

  pS := PChar(S);

  Result := SearchBuf(pS,Length(S),Length(S) - Offset,Length(S),SubString,[]) - pS;

end;

Open in new window

0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 45

Assisted Solution

by:aikimark
aikimark earned 50 total points
ID: 24404513
@ThievingSix

Beware of strings that might contain a null character (ASCII 0).  PChar casting won't work.

=================
@Sunsales

* If you reversed both the search string and the searched string, you could use intrinsic Delphi functions. see snippet

* Also, consider replacing Pos() with AnsiPos() for deprecation protection.

* The PosN() function in this library has a FromTheRight parameter.
http://delphi.icm.edu.pl/ftp/d40free/cstrings.zip

* And there is this EE solution:
http://www.experts-exchange.com/Q_20892572.html
____________________
{From http://delphi.about.com/od/adptips2004/a/bltip0904_2.htm}

function LastPos(const SubStr: String; const S: String): Integer;

begin

   result := Pos(Reverse(SubStr), Reverse(S)) ;
 

   if (result <> 0) then

     result := ((Length(S) - Length(SubStr)) + 1) - result + 1;

end;

Open in new window

0
 
LVL 26

Assisted Solution

by:EddieShipman
EddieShipman earned 50 total points
ID: 24413414
I have use these for years:

function RatStr(InStr: String; SearchStr: String): Integer;

function RatChar(S:String; C: Char):Integer;
 
 

{ Returns the position of the right most found occurrence for

  SearchStr in InStr; returns 0 if SearchStr has not been found. }
 

function RatStr(InStr: String; SearchStr: String): Integer;

var

  lb_Done:        Boolean;

  li_Pos, li_Len: Integer;

Begin

  Result := 0;

  lb_Done:= False;

  li_Len := Length(SearchStr);

  li_Pos := Length(InStr) - li_Len;

  while not lb_Done do

  begin

    if Copy(InStr,li_Pos,li_Len) = SearchStr then

    begin

      Result := li_Pos;

      lb_Done:= True;

    end;

    if li_Pos = 1 then

    begin

      lb_Done:= True;

    end;

    Dec(li_Pos,1);

  end;

end;
 

{ Returns the position of the right most found occurrence for

  C in S; returns 0 if C has not been found. }
 

function RatChar(S:String; C: Char):Integer;

var

  i: Integer;

begin

  i := Length(S);

  while (S[i] <> C) and (i > 0) do

    Dec(i);

  Result := i;

end;

Open in new window

0
 
LVL 45

Expert Comment

by:aikimark
ID: 24413713
If performance is an issue...

There is the FastPosBack() function in the FastStrings library:
http://www.koders.com/delphi/fidFB386C5C240FD5E72013C882ADD7600FDF60E6C7.aspx?s="Peter+Morris"#L3

Also, you might read the ziolko comments and examples from this thread.  Granted, we were only looking for a single character, but the  searching-for-character functionality could be incorporated into a routine that repeatedly finds the first/last/least-frequently-used character in your search-for string.
http://www.experts-exchange.com/Q_23719803.html
0
 

Assisted Solution

by:Mayazcherquoi
Mayazcherquoi earned 50 total points
ID: 24472176
Do something similar to below =)


function StrRvr(s: String): String;

var

  i, sl: Integer;

begin

  sl := Length(s);

  for i:=1 to sl do

    Result[i] := s[sl - i];

end;
 

function RandomRange(s1, s2: Integer): Integer;

begin

  Randomize;

  Result := s1 + Random(s2);

end;
 

procedure TForm1.Button1Click(Sender: TObject);

var

  s: String;

begin

  s := IntToStr(RandomRange(1000, 10000));

  Pos('3', StrRvr(s));

end;

Open in new window

0
 

Expert Comment

by:Mayazcherquoi
ID: 24472190
To edit my original post:

From what i know, there is no current function to reverse the Pos or PosEx functions, only a function you can make yourself to reverse the string =)
0
 
LVL 45

Expert Comment

by:aikimark
ID: 24507392
If you are writing a .Net application, then the CLR provides such a search-backwards function.  

Your research is correct -- there is no native function to do this in Delphi Win32 applications.  You must use a custom function for this.  It does not matter whether you write your own function, use one of the functions posted in this thread, find your own posted on the web, or use one provided by a third party software.

We have provided you at least one example of using native Delphi functions to provide the same information as a reverse Pos/PosEx function.  You don't have to package these in a function.
0
 

Author Closing Comment

by:Sunsales
ID: 31582134
Thanx all, sorry for late response.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now