Ну я как-то извращался. Фрагмент юнита.
| Код | unit Common;
interface
uses Windows, SysUtils, DateUtils, IniFiles, Controls, Forms, Dialogs, Registry, StdCtrls, Grids, ShellAPI, SHFolder, ComCtrls;
type
TChars=set of Char;
var
Letters:TChars=['A'..'Z','a'..'z']; Digits:TChars=['0'..'9'];
function SimpleTextSearch(P,Text:String;MatchCase,FullWord,Fwd:Boolean; Start:Integer):Integer; {-1 ничего не найдено, иначе номер начала вхождения} function IsLetterOrDigit(C:Char):Boolean; function IsDividor(C:Char):Boolean; function SearchNode(Items:TTreeNodes;P:String;MatchCase,FullWord,Fwd:Boolean; Start:Integer):Integer;
implementation
function IsLetterOrDigit(C:Char):Boolean; begin case byte(C) of 48..57:Result:=true; 65..90:Result:=true; 97..122:Result:=true; 184:Result:=true; 192..255:Result:=true else Result:=false; end end;
function IsDividor(C:Char):Boolean; begin case Byte(C) of 0..32:Result:=true; 42..47:Result:=true; 58..63:Result:=true; 182:Result:=true else Result:=false; end end;
function SimpleTextSearch(P,Text:String;MatchCase,FullWord,Fwd:Boolean; Start:Integer):Integer; var pos,i,l,Last:Integer;
function CheckFullWord:Boolean; begin Result:=false; if Pos-1<>0 then if not IsDividor(Text[Pos-1]) then exit; if Pos+l<=Length(Text) then if not isDividor(Text[Pos+l]) then exit; Result:=true; end;
function CheckCase:Boolean; var s:String; begin s:=copy(Text,Pos,l); if s<>P then Result:=false else Result:=true; end;
begin
l:=Length(P); if ((length(Text)=0) or (l=0)) then begin Result:=-1; exit; end; if Fwd then begin Last:=Length(Text)-l+1; for Pos:=Start to Last do begin i:=0; while ANSICompareText(P[i+1],Text[Pos+i])=0 do begin inc(i); if i=l then begin //Проверка на слово целиком if FullWord then if not CheckFullWord then break; //Проверка на соответствие регистру if MatchCase then if not CheckCase then break; Result:=Pos; exit; end end end; end//endfor else begin for Pos:=Start-l+1 downto 1 do begin i:=0; while ANSICompareText(P[l-i],Text[Pos-i])=0 do begin inc(i); //inc(count); if i=l then begin //Проверка на слово целиком if FullWord then if not CheckFullWord then break; //Проверка на соответствие регистру if MatchCase then if not CheckCase then break; Result:=Pos-l+1; exit; end end; end; end; Result:=-1; end;
end.
|
Кстати, Fwd можно сделать целочисленным и давать ему 1 и -1, а вместо двух for использовать один while прибавляя к счетчику в каждой итерации Fwd. Странно, что я тогда не додумался. |