Das wird aber eine Lange Phase. Von wo bis wo denn? PB 4.10 bis PB 99.99?
Da spiel ich lieber Phase 10...
Code: Alles auswählen
Macro Happy
 ;-)
EndMacro
Happy EndCode: Alles auswählen
Macro Happy
 ;-)
EndMacro
Happy EndCode: Alles auswählen
quell$="Diese Prozedur sucht nicht von hinten, sondern fängt in der Mitte an. Deshalb ist diese Prozedur in vielen Fällen schneller als der Originalcode von Edel und auch schneller als die meisten hier vorgestellten Prozeduren."
such$ ="Edel"
Procedure.l FindLastString(heuhaufen.s, nadel.s, CaseSensitive=1) 
Protected pos = 0
Protected lastpos=0
Protected start=Len(heuhaufen)/2 ; <-- im 1.Repeat ab Mitte suchen
If CaseSensitive = 0 
   heuhaufen = LCase(heuhaufen) 
   nadel = LCase(nadel) 
EndIf 
  
Repeat 
  lastpos = pos 
  pos = FindString(heuhaufen,nadel,start+pos+1) 
  start=0
Until pos = 0 
If lastpos
    ProcedureReturn lastpos
Else
    pos = 0
    lastpos=0    
    Repeat 
      lastpos = pos 
      pos = FindString(heuhaufen,nadel,start+pos+1) 
    Until pos = 0 
EndIf
ProcedureReturn lastpos
EndProcedure
p=FindLastString(quell$, such$)
Debug p
Code: Alles auswählen
Procedure FindLastString(String$, StringToFind$, CaseInSensitive=0)
	Protected length=Len(StringToFind$), *position=@String$+(Len(String$)-length)<<#PB_Compiler_Unicode
	If StringToFind$
		While *position >= @String$
			If CompareMemoryString(*position, @StringToFind$, CaseInSensitive, length) = #PB_String_Equal
				ProcedureReturn (*position-@String$)>>#PB_Compiler_Unicode+1
			EndIf
			*position-SizeOf(Character)
		Wend
	EndIf
EndProcedure
Debug FindLastString("berthold", "hold")Code: Alles auswählen
Macro Happy
 ;-)
EndMacro
Happy EndCode: Alles auswählen
mem = StrRStrI_(@"Ich liebe PureBasic! Du auch?",0,@"liebe")
Parameters
pszSource
[in] Pointer to a null-terminated source string.
pszLast
[in] Pointer into the source string that defines the range of the search. Set pszLast to point to a character in the source string, and the search will stop with the preceding character. Set pszLast to NULL to search the entire source string.
pszSrch
[in] Pointer to the substring to search for.
Return Value
Returns the address of the last occurrence of the substring if successful, or NULL otherwise.
Code: Alles auswählen
Procedure FindLastString(String$, StringToFind$) 
  For i=1 To CountString(String$, StringToFind$)
    temp$=StringField(String$, i, StringToFind$)
    pos=pos+Len(temp$)+1
  Next i
  ProcedureReturn pos
EndProcedure
Debug FindLastString("anna", "a")
Code: Alles auswählen
Procedure.l inMemStrRev(StartPos, *Source, strStr.s)
  
  ; naiver Algorithmus überprüft ein gesuchtes Muster rückwärts 
  ; an allen Positionen i eines Speicherbereichs beginnend bei 
  ; StartPos, Ende der Suche bei *Source
  
  result.l
  PatLen = Len(strStr)
  
  ;init pointers etc.
  MOV Ebx,strStr    ; Ebx = Pointer to first Char in string
  MOV Edx,*Source
  MOV Ecx,Edx   ; Ecx = Pointer to akt. Char in source
  ADD Ecx,StartPos  ; set source-pointer to startposition
  SUB Ecx, PatLen
  DEC Edx
  ;INC Ecx      ; StartPos - 1
  
  ! rpt_SrcRev:        ; startpoint for loop scanning through the source
  MOV al,[Ecx]
  DEC Ecx           ; Ecx + 1
  CMP Ecx,Edx          ; if null (end of source-string)
  JS endProcRev        ; -> end Procedure, Result=0
  
  CMP byte[Ebx],al  ; if found first Char of strStr look for the rest
  JNE rpt_SrcRev       ; else go on with next Char in source
  
  ;found the first Char of strStr in source
  ;now look if the rest does match
  Xor Edi,Edi             ; Edi = 0, Edi = Pointer to akt. Char in strStr
  ! rpt_StrRev:              ; startpoint for loop pounding the string
  INC Edi                 ; Edi + 1 (the first Char in string is already found)
  
  CMP byte[Ebx+Edi],0     ; if 0 (end of strStr) 
  JE got_itRev               ; -> got it, all Chars of the string did match
  MOV al,byte[Ecx+Edi+1]  ; move actual Char in source to accumulator, have 
  ; to add 1 cause Ecx already decreased before
  
  CMP byte[Ebx+Edi],al    ; if actual Char in source (Ebx+Edi) = act Char in string (al)
  JE rpt_StrRev              ; then take next Char
  JMP rpt_SrcRev             ; and go on with scanning source
  
  ! got_itRev:
  ;Result = Ecx - Source, to get the place in the source-string
  SUB Ecx,Edx
  INC Ecx
  MOV result,Ecx
  
  ! endProcRev:
  ProcedureReturn result
EndProcedure
; und zum testen 
Macro FindReport()
  PrintN ("pattern found at position: " + Str(a) + " in " + Str(timeGetTime_()-StartTime ) + " milliseconds")
  PrintN (" ")
  a=0
EndMacro
Text.s="axbbaaxbbaaxbbabbal axbbaaxbbaaxbbabbal axbbaaxbbaaxbbabbalaxbbaaxbbaaxbbabbal This is any Text of any number of characters With no content"
findstr.s= "many"
OpenConsole()
For i = 1 To 20;8
  Text=Text+"|"+Text
Next
Text=findstr+Text
loopcount = 10;2;5000
PrintN ("starting to search " + Str(loopcount) + " times, in " + Str(Len(Text)) + " characters, for '" + findstr + "'")
PrintN (" ")
PrintN ("Search inMemStrRev")
lentxt=Len(Text)
lenfindstr=Len(findstr)
StartTime = timeGetTime_()
For i = 1 To loopcount
  a=inMemStrRev(lentxt, @Text, findstr)
Next i
FindReport()