...die letzte Position eines Substrings in einem String ermitteln?

Autor: Marc Dürst
Homepage: http://www.idev.ch

Kategorie: Strings

{1.}
{
  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;

{*************************************************************}
// by Manuel Wiersch
{2.}
function LastPos(const SubStr: AnsiString; const S: AnsiString): LongInt;
asm
        
TEST    EAX,EAX         // EAX auf 0 prüfen (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]     // Länge von S  ins Zählregister
        
MOV     EDX,[ESI-4]     // Länge 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 Stringdurchläufe
                                // = 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         { Zähleregister, ESI und EDI sichern, da nun der
                                  Vergleich durchgeführt wird ob die nachfolgenden
                                  Zeichen von SubStr in S vorhanden sind }
        
PUSH    ESI
        PUSH    EDI
        MOV     ECX,EDX         // Länge 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 erhöhen, um die Position des 1. Zeichens zu
                                // bekommen
@@exit:
        POP     EDI
        POP     ESI
        POP     EBX
@@noWork:         CLD;          // DirectionFlag löschen
end;

 

printed from
www.swissdelphicenter.ch
developers knowledge base