Нахождение последнего вхождения подстроки в строку
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