Page 1 of 2

Findstring from the End

Posted: Thu Feb 13, 2014 11:55 am
by Kwai chang caine
Hello

It's a very little bit request, but i use all the time StringField and find she is a little bit restrited in the parameter.
It's cool, now there are the #PB_String_CaseSensitive adding 8)

But a reverse research, with a negative start position, will be very usefull, i found.
I use it often for parsing HTML code 8)

Code: Select all

a$ = "Hello i'm KCC for ever"
Debug "Found the letter "o", start to 3e character from the begining = " + FindString(a$, "o", 1)
Debug "Found the letter "o", start to 3e character from the end = " +  FindString(a$, "o", -1)
debugger wrote:Found the letter "o", start to 3e character from the begining = 5
Found the letter "o", start to 3e character from the end = 16
Thanks 8)

Re: Findstring from the End

Posted: Thu Feb 20, 2014 2:47 pm
by naw
How about

Code: Select all

Debug FindString(ReverseString("abcdefghijklmn"),"f")

Re: Findstring from the End

Posted: Fri Feb 21, 2014 6:18 pm
by Kwai chang caine
Hello NAW :D
It's always possible to create this function, but it's not also simple :wink:
This is your code :

Code: Select all

a$ = "Hello i'm KCC for ever"
Debug "Found the letter ''o'', start To 1er character from the begining = " + FindString(ReverseString(a$),"o")
Your code return
Debugger wrote:Found the letter ''o'', start To 1er character from the begining = 7
So in fact, your result give to me, the position of the "o" begin to the end.
You result say to me, i have a "o" in the 7e position, and my result with "-1" say to me, i have a "o" at the 16e position :wink:

The result i search to have, is begining the research to the end, but having result since the start, like the native function.
The native function, give the result by report to the start

Code: Select all

a$ = "Hello i'm KCC for ever"
Debug "Found the letter ''o'', start To 1er character from the begining = " + FindString(a$,"o")
Debugger wrote:Found the letter ''o'', start To 1er character from the begining = 5
The first "o" is at the 5e position start to the begin of the sentence
So me i want the position of the last "o" because i want to a reverse start with my negative position

Code: Select all

a$ = "Hello i'm KCC for ever"
Debug "Found the letter "o", start to 3e character from the begining = " + FindString(a$, "o", 1) <=== Native function
Debug "Found the letter "o", start to 3e character from the end = " +  FindString(a$, "o", -1) < Request funtion
Debugger wrote:Found the letter "o", start to 3e character from the begining = 5 <=== Native function
Found the letter "o", start to 3e character from the end = 16 <=== Request function
It's not so simple, and if you search several character, it's worst :lol:
Because you must reverse the sentece searched too

Code: Select all

a$ = "Hellor i'm KCC for ever"
Debug "Found the sentence ''or'', start To 1er character from the begining = " + FindString(ReverseString(a$), ReverseString("or"))
Debugger wrote:Found the sentence ''or'', start To 1er character from the begining = 6
And me i want the result
Debugger wrote:Found the sentence ''or'', start To 1er character from the begining = 16

Re: Findstring from the End

Posted: Fri Feb 21, 2014 8:08 pm
by uwekel
+1
It has been requested so many times, but not yet implemented :-(

Re: Findstring from the End

Posted: Fri Feb 21, 2014 8:10 pm
by uwekel
Not that fast but working:

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

Re: Findstring from the End

Posted: Fri Feb 21, 2014 8:21 pm
by Kwai chang caine
Hello UWEKEL :D

You not know how you make me happy 8)
Since this time, i believe i alone in all the world, to want this function :cry:
And worst...i believe everybody think i'm mad, so ....not need to this function, for everybody think, i'm crazy :mrgreen: :lol:

Thanks for your code 8)
In fact i have try to accomplish this function with the native Findstring()...but it's incredible how it's not really simple :shock:
I have made several code, and there are always a problem in my HTML code.

Finally, i have do like you and use loop, it's the most simple solution

Again thanks for your agree :wink: we are two now in the world :lol:

Re: Findstring from the End

Posted: Fri Feb 21, 2014 9:54 pm
by wilbert
uwekel wrote:Not that fast but working:
A version using CompareMemoryString might be faster.

Re: Findstring from the End

Posted: Fri Feb 21, 2014 11:34 pm
by skywalk

Code: Select all

Procedure.i FindStringRev(String$, StringToFind$, UseCase.i=#PB_String_CaseSensitive)
  ;Debug FindStringRev("123-abc-123", "23") ; = 10, <> 2
  ;Debug FindStringRev("123-abc-123-ABC", "a", #PB_String_NoCase) ; = 13
  Protected.i length = Len(StringToFind$)
  Protected.i *pos = @String$ + (Len(String$)-length) * SizeOf(Character)
  While @String$ <= *pos
    If CompareMemoryString(*pos, @StringToFind$, UseCase, length) = #PB_String_Equal ; = 0
      ProcedureReturn (*pos - @String$) / SizeOf(Character) + 1
    EndIf 
    *pos - SizeOf(Character)
  Wend 
  ProcedureReturn 0
EndProcedure 

Re: Findstring from the End

Posted: Sat Feb 22, 2014 5:28 am
by Thunder93
Good ol days.. I use to really enjoy watching Kung Fu (TV series).

Anyways... I heard your cries. You want FindString() to do both ways? No sweat. :wink:

Now let's leave Fred alone so he can focus on the big game. :lol:

Code: Select all

Procedure.l FindStringReverse(String.s, StringToFind.s, StartPosition=0, Mode=0)
  StrLen.l = Len(String) : Str2FindLen.l = Len(StringToFind)
  If Not Str2FindLen : ProcedureReturn 0 : EndIf  
 
  fResult = FindString(ReverseString(String), ReverseString(StringToFind) , StartPosition, Mode)
  
  If Not fResult : ProcedureReturn 0 : EndIf 
  Result = (fResult + Str2FindLen)-2
  
 ProcedureReturn StrLen-Result
EndProcedure


Procedure _FindString(String$, StringToFind$, StartPosition = 0, Mode = 0)
 
  If StartPosition >= 0 : fReturn =  FindString(String$, StringToFind$, StartPosition, Mode)
  Else : fReturn = FindStringReverse(String$, StringToFind$, StartPosition, Mode)
  EndIf 
  
  ProcedureReturn fReturn
EndProcedure

Macro FindString(String, StringToFind, StartPosition = 0, Mode = 0)
    _FindString(String, StringToFind, StartPosition, Mode)
EndMacro


sS2.s = "Hello i'm KCC for ever"
; Ss2.s = "Hellor i'm KCC for ever"

StartTime = ElapsedMilliseconds()
FoundPos.l = FindString(Ss2, "o", -1)
ElapsedTime = ElapsedMilliseconds()-StartTime
Debug "FindStringReverse:  ElapsedTime["+Str(ElapsedTime)+"]: Found Position: "+FoundPos
Debug Mid(Ss2, FoundPos)
Debug "----"

StartTime1 = ElapsedMilliseconds()
FoundPos1.l = FindString(Ss2, "o")
ElapsedTime1 = ElapsedMilliseconds()-StartTime1
Debug "FindString: ElapsedTime["+Str(ElapsedTime1)+"]: Found Position: "+FoundPos1
Debug Mid(Ss2, FoundPos1)
Debug "---"

Re: Findstring from the End

Posted: Sat Feb 22, 2014 9:07 am
by wilbert
Here's a version based on the code of Skywalk supporting a negative StartPosition.

Code: Select all

#CharShift = SizeOf(Character) - 1

Procedure.i FindStringRev(String$, StringToFind$, StartPosition = -1, Mode = #PB_String_CaseSensitive)
  Protected.i *Str, SLen = Len(String$), STFLen = Len(StringToFind$)
  If StartPosition + STFLen > 0
    StartPosition = SLen - STFLen
  Else
    StartPosition + SLen
  EndIf
  If StartPosition >= 0
    *Str = @String$ + StartPosition << #CharShift
    While *Str >= @String$
      If CompareMemoryString(*Str, @StringToFind$, Mode, STFLen) = #PB_String_Equal
        ProcedureReturn (*Str - @String$) >> #CharShift + 1
      EndIf 
      *Str - SizeOf(Character)
    Wend 
  EndIf
  ProcedureReturn 0
EndProcedure
Another approach using FindString

Code: Select all

Procedure.i FindStringRev(String$, StringToFind$, StartPosition = -1, Mode = #PB_String_CaseSensitive)
  Protected.i Pos, PrevPos, MaxPos
  MaxPos = Len(String$) + StartPosition + 1
  Repeat
    PrevPos = Pos
    Pos = FindString(String$, StringToFind$, Pos + 1, Mode)
  Until Pos = 0 Or Pos > MaxPos
  ProcedureReturn PrevPos
EndProcedure
Example

Code: Select all

Debug FindStringRev("Hello i'm not KCC for ever", "kcc", -5, #PB_String_NoCase) 

Re: Findstring from the End

Posted: Sun Feb 23, 2014 5:44 pm
by Kwai chang caine
Waoooouuh !! :shock:
First thanks a lot at you all my friends 8)

Sure ... it's a "little" more quick like answer, that have a day a native function :mrgreen:
Good ol days.. I use to really enjoy watching Kung Fu (TV series).
Yes !!! in fact in this forum, i feel like the "little beetle" (Nickname give by master PO in the french serie "Grasshopper" apparently in the english) in the shaolin monastery

It's for that i have choose this nickname "Kwaï chang caïne"
First because i love Kung-fu (Tv serie), like also art martial, bruce lee, etc...
Love all this value taught in the temples: "Discipline, Respect, Wisdom, Work, Precision, Recognition, Politeness, Mastery, Power, Efficiency, speed"
So, numerous value KCC found in this forum surrounded by all this MASTERS 8) 8)

At the begining of PB (8 years ago), i have another nickname, and quickly i have change for KCC, because in my head, it's what i feel all the day with you all 8)

Image

I have understand since 8 years, what happiness it is, to live and touch with the finger ....the pure knowledge...
In fact a little bit like a children live with his dad, his father who always knows :shock:
Several person not believe me...but it's exactely and strictly the truth :wink:
Now let's leave Fred alone so he can focus on the big game
No no no.....i would say rather, FRED now have the choice to copy/paste one of this code for include it in the future version....the works is do :lol:

In all case, i have learn several things :
1/ Several way for do my request 8)
2/ It's not so simple for just do a reverse research (FRED if you read me :wink:)
3/ It's possible to use a MACRO with the same name of a native function :shock:

Have a good end of week-end all...
And that the shaolins gods protect you all...MASTERS 8)
http://www.youtube.com/watch?v=kCBzLPgLRWs

Re: Findstring from the End

Posted: Sun Feb 23, 2014 6:00 pm
by TI-994A
Thunder93 wrote:Good ol days.. I use to really enjoy watching Kung Fu (TV series)...
Good memories. Sad, though, how Bruce Lee was ripped-off. :(

Re: Findstring from the End

Posted: Sun Feb 23, 2014 6:30 pm
by Kwai chang caine
Because for producers of the time, Bruce lee is too much chinese and too little for do this.
The producer prefer David carradine, more impressive...
Bruce are much annoyed by this decision :cry:

Like what, the real power is not always what the eyes see :wink:

Re: Findstring from the End

Posted: Sun Feb 23, 2014 6:53 pm
by TI-994A
Kwaï chang caïne wrote:The producer prefer David carradine, more impressive...
True, although the rest of his acting career wasn't as impressive. Hollywood grades him only as a B-lister.

Re: Findstring from the End

Posted: Sun Feb 23, 2014 6:59 pm
by Kwai chang caine
Yes, perhaps he not have the career at the level of his talent :cry:
And his end, not glorious too :|