Mega Code Archive

 
Categories / Delphi / Strings
 

How to Find a Substring in a String starting from any position in the String

Title: How to Find a Substring in a String starting from any position in the String 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 } { 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 { 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