Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1050
  • Last Modified:

Can i revert the PosX function?

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
Paer Toernell
Asked:
Paer Toernell
  • 3
  • 2
  • 2
  • +4
5 Solutions
 
rfwoolfCommented:
Hmmm i guess you could reverse your string and your searchterm, and then use posex. I'll keep thinking
0
 
rfwoolfCommented:
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
 
JosephGloszCommented:
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
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
Paer ToernellAuthor Commented:
I was thinking of revers the string - but it can be quite large - so i would prefer another solution because of time efficiency.
0
 
JosephGloszCommented:
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
 
ThievingSixCommented:
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
 
ThievingSixCommented:
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
 
aikimarkCommented:
@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
 
Eddie ShipmanAll-around developerCommented:
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
 
aikimarkCommented:
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
 
MayazcherquoiCommented:
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
 
MayazcherquoiCommented:
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
 
aikimarkCommented:
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
 
Paer ToernellAuthor Commented:
Thanx all, sorry for late response.
0
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.

Join & Write a Comment

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 3
  • 2
  • 2
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now