Page 1 of 2
FindStringReverse()
Posted: Thu Dec 04, 2008 12:52 pm
by PB
Any plans to implement such a command? Been requested before but never
done. Or maybe if the "StartPosition" flag of "FindString()" is bigger than the
length of the string, then the string is searched in reverse? Example:
Code: Select all
Debug FindString("hello","l",1) ; Returns 3 because first "l" is at position 3.
Debug FindString("hello","l",6) ; Returns 4 because first "l" from end is at position 4.
Or even just a dedicated flag for it:
Code: Select all
Debug FindString("hello","l",#PB_FindString_End) ; Returns 4 like the other example.
Posted: Thu Dec 04, 2008 1:06 pm
by naw
More Useful would be a
command - you could use the regular
as usual.
Posted: Thu Dec 04, 2008 1:14 pm
by PB
No, reversing the string and doing a FindString gives the wrong result:
Code: Select all
Debug FindString("olleh","l",1) ; Incorrectly returns 2, not 4.
But I agree that PureBasic is missing a ReverseString() command too.

Posted: Mon Dec 08, 2008 12:42 pm
by naw
Oh - maybe my understanding of what a ReverseFindString is incorrect then. I presumed it would search from right to left - so
should return 3
and
Code: Select all
FindString(ReverseString("1234"),"3",0
should return 2
But I see that you want to do something different - Do you want to find a certain instance of a string such as:
Code: Select all
FindStringInstance("123412341234","4",2)
would return 8
Yes - that would be very useful...
Posted: Mon Dec 08, 2008 5:02 pm
by Michael Vogel
The "only" useful function would be (something like) ReverseFindString.
Using a parameter bigger than the length of a string would never allow to find the second occurence of a substring from the right
Example:
Find the directory name "THIS" from a path like "C:\win\sys\a\THIS\x.dll"
Code: Select all
right=ReverseFindString(path.s,"\",#MAXINT)
if right : left=ReverseFindString(path.s,"\",right-1)
if left : dir.s=Mid(path.s,left+1,right-left-1) : endif : endif
Reversing the string itself wouldn't be useful for normal
Michael
Posted: Mon Dec 08, 2008 7:16 pm
by blueznl
I'd rather call it RFindString...
Re: FindStringReverse()
Posted: Sat Dec 22, 2012 2:36 pm
by uwekel
Ok, this thread is really old, but i just found it and for me it is new

I did this work-around for the missing command:
Code: Select all
Procedure FindStringReverse(String.s, StringToFind.s, StartPosition=0)
Protected x
;returns the most right position of StringToFind
If Not StartPosition
StartPosition = Len(String)
EndIf
For x = StartPosition To 1 Step -1
If Mid(String, x, Len(StringToFind)) = StringToFind
Break
EndIf
Next
ProcedureReturn x
EndProcedure
Anyhow i would appreciate an embedded and most likely much faster version!
Re: FindStringReverse()
Posted: Sat Dec 22, 2012 7:33 pm
by skywalk
This is faster.
Code: Select all
Procedure.i SF_FindStringRev(String$, StringToFind$, UseCase.i=#PB_String_CaseSensitive)
Protected.i length = Len(StringToFind$)
Protected.i *position = @String$ + (Len(String$)-length) * SizeOf(Character)
While @String$ <= *position
If CompareMemoryString(*position, @StringToFind$, UseCase, length) = #PB_String_Equal ; = 0
ProcedureReturn (*position - @String$) / SizeOf(Character) + 1
EndIf
*position - SizeOf(Character)
Wend
ProcedureReturn 0
EndProcedure
Debug SF_FindStringRev("123-abc-123","23") ; = 10, <> 2
Debug SF_FindStringRev("123-abc-123-ABC","a",#PB_String_NoCase) ; = 13
Re: FindStringReverse()
Posted: Sun Dec 23, 2012 9:14 am
by uwekel
Cool, especially on longer strings it is very much faster!
Re: FindStringReverse()
Posted: Sun Dec 23, 2012 1:10 pm
by luis
uwekel wrote:Cool, especially on longer strings it is very much faster!
Originally posted by AND51 here ->
http://www.purebasic.fr/german/viewtopi ... 71#p148871
... with many other similar procs.
Re: FindStringReverse()
Posted: Tue Dec 25, 2012 9:17 pm
by davido
Wouldn't the simple code below also do the job?
It seems fast enough at about 50,000,000 per second.
Code: Select all
FindString(ReverseString("Hello K WorKld"),"K")
Re: FindStringReverse()
Posted: Tue Dec 25, 2012 9:43 pm
by skywalk
Not always. For very long strings, you will suffer the entire ReverseString() before you begin your search.

Re: FindStringReverse()
Posted: Wed Dec 26, 2012 1:41 am
by MachineCode
Code: Select all
FindString(ReverseString("Hello K WorKld"),"K")
That returns 3, not 12. The original request wants the last position in the string, as shown in the example.
Re: FindStringReverse()
Posted: Wed Dec 26, 2012 4:17 am
by skywalk
Yeah, I understood what he was implying. I still think it's faster/easier to search from the end.
Code: Select all
s$ = "Hello K WorKld"
Debug Len(s$) + 1 - FindString(ReverseString(s$),"K")
Debug Len(s$) + 1 - FindString(ReverseString(s$),"l")
Re: FindStringReverse()
Posted: Wed Dec 26, 2012 2:46 pm
by davido
Thanks Skywalk.
Yes, you are right for very long strings it could be a problem.
I've kept a template of your code as it is a nice lesson in using memory.
My current requirement is not affected by speed and the strings are small.
Timings on my Core i3 at 3 GHZ for 1 million iterations are:
10 chars: 90ms
100 chars: 390ms
1000 chars: 3,950ms
10,000 chars: 39,000ms
Code: Select all
EnableExplicit
Define A$, MS1$, MS2$, Dt.I, M.I
A$=RSet("Hello K WorKld",100,"A")
Dt=ElapsedMilliseconds()
For M=1 To 1000000
FindString(ReverseString(A$),"K")
Next M
MS1$ = "Time for: "+Str(M-1)+" iterations:"
MS2$ = Str(ElapsedMilliseconds()-Dt)+"ms Place = "+Str(FindString(ReverseString("Hello K WorKld"),"K"))
MessageRequester(MS1$,MS2$)