Sources
Delphi Russian Knowledge Base
DRKB - это самая большая и удобная в использовании база знаний по Дельфи в рунете, составленная Виталием Невзоровым

Нахождение последнего вхождения подстроки в строку

01.01.2007
{ **** UBPFD *********** by delphibase.endimus.com ****
>> Нахождение последнего вхождения подстроки в строку
 
Функция возвращает начало последнего вхождения
подстроки FindS в строку SrcS, т.е. первое с конца.
Если возвращает ноль, то подстрока не найдена.
Можно использовать в текстовых редакторах
при поиске текста вверх от курсора ввода.
 
Зависимости: System
Автор:       Fenik, chook_nu@uraltc.ru, Новоуральск
Copyright:   Автор: Федоровских Николай
Дата:        16 июня 2002 г.
***************************************************** }
 
function PosR2L(const FindS, SrcS: string): Integer;
{Функция возвращает начало последнего вхождения
 
подстроки FindS в строку SrcS, т.е. первое с конца.
 
Если возвращает ноль, то подстрока не найдена.
 
Можно использовать в текстовых редакторах
 
при поиске текста вверх от курсора ввода.}
 
 
function InvertS(const S: string): string;
   
{Инверсия строки S}
 
var
    i
, Len: Integer;
 
begin
   
Len := Length(S);
   
SetLength(Result, Len);
   
for i := 1 to Len do
     
Result[i] := S[Len - i + 1];
 
end;
 
var
  ps
: Integer;
begin
 
{Например: нужно найти последнее вхождение
   
строки 'ро' в строке 'пирожок в коробке'.
   
Инвертируем обе строки и получаем
     
'ор' и 'екборок в кожорип',
   
а затем ищем первое вхождение с помощью стандартной
   
функции Pos(Substr, S: string): string;
   
Если подстрока Substr есть в строке S, то
   
эта функция возвращает позицию первого вхождения,
   
а иначе возвращает ноль.}
  ps
:= Pos(InvertS(FindS), InvertS(SrcS));
 
{Если подстрока найдена определяем её истинное положение
   
в строке, иначе возвращаем ноль}
 
if ps <> 0 then
   
Result := Length(SrcS) - Length(FindS) - ps + 2
 
else
   
Result := 0;
end;
Пример использования:
 
p
:= PosR2L('са', 'Мой сапог догнал самолёт.'); // p:=18;

{ 
 
Letzte Position von SubStr in S ermitteln.
 
Returns the last occurence of SubStr in S.
}
 
 
function LastPos(SubStr, S: string): Integer;
 
var
   
Found, Len, Pos: integer;
 
begin
   
Pos := Length(S);
   
Len := Length(SubStr);
   
Found := 0;
   
while (Pos > 0) and (Found = 0) do
   
begin
     
if Copy(S, Pos, Len) = SubStr then
       
Found := Pos;
     
Dec(Pos);
   
end;
   
LastPos := Found;
 
end;
 

Взято с сайта: https://www.swissdelphicenter.ch

 

 


// by Manuel Wiersch 
 
 
function LastPos(const SubStr: AnsiString; const S: AnsiString): LongInt;
 
asm
         TEST    EAX
,EAX         // EAX auf 0 prufen (d.h. SubStr = nil)
        JE      @@noWork        
// wenn EAX = 0 dann Sprung zu noWork
        TEST    EDX
,EDX
         
// Test ob S = nil
        JE      @@stringEmpty  
// bei Erfolg -> Sprung zum Label 'stringEmpty'
        PUSH    EBX
         PUSH    ESI
         PUSH    EDI            
// Register auf dem Stack sichern  Grund: OH
                               
// OH: "In einer asm-Anweisung mu? der Inhalt
                               
// der Register EDI, ESI, ESP, EBP und EBX
                               
// erhalten bleiben (dh. vorher auf dem Stack
                               
// speichern)         MOV     ESI, EAX
                               
// ESI = Sourceindex      -> Adresse vom SubStr
        MOV     EDI
, EDX        // EDI = Destinationindex -> Adresse von S
        MOV     ECX
,[EDI-4]     // Lange von S  ins Zahlregister
        MOV     EDX
,[ESI-4]     // Lange des SubStr in EDX
        DEC     EDX            
// Length(SubStr) - 1
        JS      @@fail
         
// Vorzeichenbedingter Sprung (JumpIfSign)
                               
// d.h. (EDX < 0) -> Sprung zu 'fail'
        STD
;                    // SetDirectionFlag -> Stringroutinen von hinten
                               
// abarbeiten
        ADD     ESI
, EDX        // Pointer auf das letzte Zeichen vom SubStr
        ADD     EDI
, ECX
         DEC     EDI            
// Pointer auf das letzte Zeichen von S
        MOV     AL
, [ESI]       // letztes Zeichen des SubStr in AL laden
        DEC     ESI            
// Pointer auf das vorletzte Zeichen setzen.
        SUB     ECX
, EDX        // Anzahl der Stringdurchlaufe
                               
// = Length(s) - Length(substr) + 1
        JLE     @@fail          
// Sprung zu 'fail' wenn ECX <= 0
@@loop
:
         REPNE   SCASB          
// Wdh. solange ungleich (repeat while not equal)
                               
// scan string for byte
        JNE     @@fail
         MOV     EBX
,ECX         { Zahleregister, ESI und EDI sichern, da nun der
                                 
Vergleich durchgefuhrt wird ob die nachfolgenden
                                 
Zeichen von SubStr in S vorhanden sind }
         PUSH    ESI
         PUSH    EDI
         MOV     ECX
,EDX         // Lange des SubStrings in ECX
        REPE    CMPSB          
// Solange (ECX > 0) und (Compare string fo byte)
                               
// dh. solange S[i] = SubStr[i]
        POP     EDI
         POP     ESI            
// alten Source- und Destinationpointer vom Stack holen
        JE      @@found        
// Und schon haben wir den Index da ECX = 0
                               
// dh. alle Zeichen wurden gefunden
        MOV     ECX
, EBX        // ECX wieder auf alte Anzahl setzen und
        JMP     @@loop          
// Start bei 'loop'
@@fail
:
         XOR     EAX
,EAX         // EAX auf 0 setzen
        JMP     @@exit @@stringEmpty
:
         XOR     EAX
,EAX
         JMP     @@noWork @@found
:
         MOV     EAX
, EBX        // in EBX steht nun der aktuelle Index
        INC     EAX            
// um 1 erhohen, um die Position des 1. Zeichens zu
                               
// bekommen
@@exit
:
         POP     EDI
         POP     ESI
         POP     EBX
 @@noWork
:         CLD;          // DirectionFlag loschen
end;

Взято с сайта: https://www.swissdelphicenter.ch