Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Library: Algorithmen (https://www.delphipraxis.net/28-library-algorithmen/)
-   -   Delphi Suchen von Strings im String (incl. Startposition) (https://www.delphipraxis.net/117-suchen-von-strings-im-string-incl-startposition.html)

sakura 12. Jun 2002 11:50


Suchen von Strings im String (incl. Startposition)
 
Hi DPler,

dieser Beitrag habe ich zum ersten Mal am 31.10.2000 bei Delphi3000.com veröffentlicht. Nach und nach werde ich verschiedene meiner Beiträge hier einbringen.

Die Lösung wurde in Borland Delphi 5 SP 1 entwickelt, sollte aber auch auf den anderen 32-bit Versionen funktionieren. Der Algorithmus basiert auf dem Original von Borlands Pos Funktion aus der Systems unit.

function NextPos(Substr: string; S: string; LastPos: DWORD = 0): DWORD

Die ersten beiden Parameter sind identisch mit der Funktion Pos von Borland. Der dritte Parameter gibt die Position an, nach welcher die Suche fortgesetzt werden soll (meistens die des letzten Treffers). 0 für von Anfang an, 1 suche ab der 2. Stelle, ..., 9 suche ab der 10. Stelle usw. usf.

Damit kann man recht schnell nach allen Vorkommen eines String in einem weiteren Suchen. Der Code ist komplett in Assembler und liesse sich weiter optimieren (siehe Delphi3000.com), aber er funktioniert. :)

Delphi-Quellcode:
function NextPos(SubStr: AnsiString; Str: AnsiString; LastPos: DWORD
  = 0): DWORD;
type
  StrRec = packed record
    allocSiz: Longint;
    refCnt: Longint;
    length: Longint;
  end;

const
  skew = sizeof(StrRec);

asm
  // Search-String passed? 
  TEST   EAX,EAX
  JE     @@noWork

  // Sub-String passed? 
  TEST   EDX,EDX
  JE     @@stringEmpty

  // Save registers affected
  PUSH   ECX
  PUSH   EBX
  PUSH   ESI
  PUSH   EDI

  // Load Sub-String pointer
  MOV    ESI,EAX
  // Load Search-String pointer
  MOV    EDI,EDX
  // Save Last Position in EBX
  MOV    EBX,ECX

  // Get Search-String Length
  MOV    ECX,[EDI-skew].StrRec.length
  // subtract Start Position
  SUB    ECX,EBX
  // Save Start Position of Search String to return
  PUSH   EDI
  // Adjust Start Position of Search String
  ADD    EDI,EBX

  // Get Sub-String Length
  MOV    EDX,[ESI-skew].StrRec.length
  // Adjust
  DEC    EDX
  // Failed if Sub-String Length was zero
  JS     @@fail
  // Pull first character of Sub-String for SCASB function
  MOV    AL,[ESI]
  // Point to second character for CMPSB function
  INC    ESI

  // Load character count to be scanned
  SUB    ECX,EDX
  // Failed if Sub-String was equal or longer than Search-String
  JLE    @@fail
@@loop:
  // Scan for first matching character
  REPNE  SCASB
  // Failed, if none are matching
  JNE    @@fail
  // Save counter
  MOV    EBX,ECX
  PUSH   ESI
  PUSH   EDI
  // load Sub-String length
  MOV    ECX,EDX
  // compare all bytes until one is not equal
  REPE   CMPSB
  // restore counter
  POP    EDI
  POP    ESI
  // all byte were equal, search is completed
  JE     @@found
  // restore counter
  MOV    ECX,EBX
  // continue search
  JMP    @@loop
@@fail:
  // saved pointer is not needed
  POP    EDX
  XOR    EAX,EAX
  JMP    @@exit
@@stringEmpty:
  // return zero - no match
  XOR    EAX,EAX
  JMP    @@noWork
@@found:
  // restore pointer to start position of Search-String
  POP    EDX
  // load position of match
  MOV    EAX,EDI
  // difference between position and start in memory is
  //   position of Sub
  SUB    EAX,EDX
@@exit:
  // restore registers
  POP    EDI
  POP    ESI
  POP    EBX
  POP    ECX
@@noWork:
end;
Also, viel Spass beim Suchen...


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz