Findstring from the End

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Findstring from the End

Post 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)
ImageThe happiness is a road...
Not a destination
naw
Enthusiast
Enthusiast
Posts: 573
Joined: Fri Apr 25, 2003 4:57 pm

Re: Findstring from the End

Post by naw »

How about

Code: Select all

Debug FindString(ReverseString("abcdefghijklmn"),"f")
Ta - N
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Findstring from the End

Post 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
ImageThe happiness is a road...
Not a destination
uwekel
Enthusiast
Enthusiast
Posts: 740
Joined: Sat Dec 03, 2011 5:54 pm
Location: Oldenburg (Germany)

Re: Findstring from the End

Post by uwekel »

+1
It has been requested so many times, but not yet implemented :-(
PB 5.70 LTS (x64) - Debian Testing, Gnome 3.30.2
uwekel
Enthusiast
Enthusiast
Posts: 740
Joined: Sat Dec 03, 2011 5:54 pm
Location: Oldenburg (Germany)

Re: Findstring from the End

Post 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
PB 5.70 LTS (x64) - Debian Testing, Gnome 3.30.2
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Findstring from the End

Post 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:
ImageThe happiness is a road...
Not a destination
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Findstring from the End

Post by wilbert »

uwekel wrote:Not that fast but working:
A version using CompareMemoryString might be faster.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Findstring from the End

Post 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 
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: Findstring from the End

Post 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 "---"
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Findstring from the End

Post 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) 
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Findstring from the End

Post 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
ImageThe happiness is a road...
Not a destination
User avatar
TI-994A
Addict
Addict
Posts: 2700
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Findstring from the End

Post 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. :(
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Findstring from the End

Post 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:
ImageThe happiness is a road...
Not a destination
User avatar
TI-994A
Addict
Addict
Posts: 2700
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Findstring from the End

Post 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.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Findstring from the End

Post by Kwai chang caine »

Yes, perhaps he not have the career at the level of his talent :cry:
And his end, not glorious too :|
ImageThe happiness is a road...
Not a destination
Post Reply