Delphi-Help

Главная Статьи Текст и Строки Как найти строку в строке, начиная с определенной позиции?

Как найти строку в строке, начиная с определенной позиции?

Оцените материал
(0 голосов)


Как найти строку в строке, начиная с определенной позиции?

function SmartPosAsm(const substr : AnsiString;
 const s : AnsiString; StartPos : Cardinal) : Integer;
type
  StrRec = packed record
    allocSiz: Longint;
    refCnt: Longint;
    length: Longint;
  end;
const
  skew = sizeof(StrRec);
asm
{     ->EAX     Pointer to substr               }
{       EDX     Pointer to string               }
{     <-EAX     Position of substr in s or 0    }
        TEST    EAX,EAX
        JE      @@noWork
 
        TEST    EDX,EDX
        JE      @@stringEmpty
 
        PUSH    EBX
        PUSH    ESI
        PUSH    EDI
 
        MOV     ESI,EAX         { Point ESI to substr           }
        MOV     EDI,EDX         { Point EDI to s                }
 
        MOV     EAX,ECX
        MOV     ECX,[EDI-skew].StrRec.length  { ECX = Length(s) }
        ADD     EDI,EAX
        SUB     ECX,EAX
 
        PUSH    EDI  { remember s position to calculate index     }
 
        MOV     EDX,[ESI-skew].StrRec.length { EDX = Length(substr)
        DEC     EDX              { EDX = Length(substr) - 1    }
        JS      @@fail           { < 0 ? return 0              }
        MOV     AL,[ESI]         { AL = first char of substr   }
        INC     ESI          { Point ESI to 2'nd char of substr}
 
        SUB     ECX,EDX       { #positions in s to look at    }
                      { = Length(s) - Length(substr) + 1      }
        JLE     @@fail
@@loop:
        REPNE   SCASB
        JNE     @@fail
        MOV     EBX,ECX          { save outer loop counter    }
        PUSH    ESI              { save outer loop substr pointer}
        PUSH    EDI              { save outer loop s pointer    }
 
        MOV     ECX,EDX
        REPE    CMPSB
        POP     EDI              { restore outer loop s pointer  }
        POP     ESI           { restore outer loop substr pointer}
        JE      @@found
        MOV     ECX,EBX          { restore outer loop counter    }
        JMP     @@loop
 
@@fail:
        POP     EDX              { get rid of saved s pointer    }
        XOR     EAX,EAX
        JMP     @@exit
 
@@stringEmpty:
        XOR     EAX,EAX
        JMP     @@noWork
 
@@found:
        POP   EDX     { restore pointer to first char of s }
        MOV   EAX,EDI { EDI points of char after match     }
        SUB   EAX,EDX { the difference is the correct index}
@@exit:
        POP     EDI
        POP     ESI
        POP     EBX
@@noWork:
end; //SmartPosAsm
 
function cnsSmartPos(const substr : AnsiString;
const s : AnsiString; StartPos : Cardinal) : Integer;
begin
  dec(StartPos);
  Result := SmartPosAsm(SubStr,S,StartPos);
  if Result > 0 then Result := Result + StartPos;
end; //cnsSmartPos

 

Ещё вариант:

S - строка, в которой искать

SubStr - образец

fromPos - с какой позиции

Все на асемблере, принцип простой - ищется первый символ, затем часть строки сравнивается с образцом начиная с этого символа. Если образец не найден, возвращает 0. Если найден - номер первого символа вхождения.

function TailPos(const S, SubStr: AnsiString;
 fromPos: integer): integer;
asm
        PUSH EDI
        PUSH ESI
        PUSH EBX
        PUSH EAX
        OR EAX,EAX
        JE @@2
        OR EDX,EDX
        JE @@2
        DEC ECX
        JS @@2
 
        MOV EBX,[EAX-4]
        SUB EBX,ECX
        JLE @@2
        SUB EBX,[EDX-4]
        JL @@2
        INC EBX
 
        ADD EAX,ECX
        MOV ECX,EBX
        MOV EBX,[EDX-4]
        DEC EBX
        MOV EDI,EAX
@@1: MOV ESI,EDX
        LODSB
        REPNE SCASB
        JNE @@2
        MOV EAX,ECX
        PUSH EDI
        MOV ECX,EBX
        REPE CMPSB
        POP EDI
        MOV ECX,EAX
        JNE @@1
        LEA EAX,[EDI-1]
        POP EDX
        SUB EAX,EDX
        INC EAX
        JMP @@3
@@2: POP EAX
        XOR EAX,EAX
@@3: POP EBX
        POP ESI
        POP EDI
end;
Прочитано 5288 раз

Авторизация



Счетчики