📄 unitsearchstring.pas
字号:
unit unitSearchString;
interface
uses Windows, Classes, SysUtils, StrUtils, unitCharsetMap;
type
TStrArray = array of string;
TStringSearcher = class
protected
fSearchString : String;
fOrWords : TStrArray;
fNotWords : TStrArray;
fAndWords : TStrArray;
nOrWords : Integer;
nAndWords : Integer;
nNotWords : Integer;
fCaseSensitive : boolean;
public
constructor Create (const ASearchString : string; AcaseSensitive : boolean);
function Matches (AString : string) : boolean;
procedure Parse (searchString : string); virtual; abstract;
property CaseSensitive : boolean read fCaseSensitive write fCaseSensitive;
end;
TGoogleLikeStringSearcher = class (TStringSearcher)
public
procedure Parse (searchString : string); override;
end;
TWStrArray = array of WideString;
TWideStringSearcher = class
protected
fCaseSensitive : boolean;
fSearchString : WideString;
fOrWords : TWStrArray;
fNotWords : TWStrArray;
fAndWords : TWStrArray;
nOrWords : Integer;
nAndWords : Integer;
nNotWords : Integer;
public
constructor Create (const ASearchString : WideString; ACaseSensitive : boolean);
function Matches (AString : WideString) : boolean;
procedure Parse (searchString : WideString); virtual; abstract;
end;
TGoogleLikeWideStringSearcher = class (TWideStringSearcher)
public
procedure Parse (searchString : WideString); override;
end;
function ExtractString (const search : string; var s : string) : string;
function SplitString (const search : string; var s : string) : string;
function SplitToken (var st : string) : string;
function DelimPos (const delims : string; const st : string; out delim : char) : Integer;
function DelimSplitString (const search : string; var s : string; out delim : char) : string;
function WideContainsText (const AText, ASubText : WideString) : boolean;
function WidePosEx(const SubStr, S: WideString; Offset: Cardinal = 1): Integer;
function WideSplitString (const search : WideString; var s : WideString) : WideString;
function WideStrScan(const Str: PWideChar; Chr: WideChar): PWideChar;
function SearchStringArray (arr : array of string; const st : string) : Integer;
function StringArrayContains (arr : array of string; const st : string) : boolean;
function WideDequotedStr (st : WideString; q : WideChar = '"') : WideString;
function WideQuotedStr (st : WideString; q : WideChar = '"') : WideString;
function WildContains (const a, b : string) : boolean;
function WWildContains (const a, b : WideString) : boolean;
implementation
// nb. Pos is a 'magic' function that internally has an (undocumented) wide version
function WideContainsText (const AText, ASubText : WideString) : boolean;
begin
result := Pos (WideUpperCase (ASubText), WideUpperCase (AText)) > 0;
end;
function WideContainsStr (const AText, ASubText : WideString) : boolean;
begin
result := Pos (ASubText, AText) > 0;
end;
function WidePosEx(const SubStr, S: WideString; Offset: Cardinal = 1): Integer;
var
I,X: Integer;
Len, LenSubStr: Integer;
begin
if Offset = 1 then
Result := Pos(SubStr, S)
else
begin
I := Offset;
LenSubStr := Length(SubStr);
Len := Length(S) - LenSubStr + 1;
while I <= Len do
begin
if S[I] = SubStr[1] then
begin
X := 1;
while (X < LenSubStr) and (S[I + X] = SubStr[X + 1]) do
Inc(X);
if (X = LenSubStr) then
begin
Result := I;
exit;
end;
end;
Inc(I);
end;
Result := 0;
end;
end;
(*----------------------------------------------------------------------*
| function ExtractString : string |
| |
| Search for a substring. If the substring is found, return the |
| characters up to the substring, and set the soure string to the |
| characters after it. If it was not found, return an empty string |
| and leave the source string unchanged. |
*----------------------------------------------------------------------*)
function ExtractString (const search : string; var s : string) : string;
var
p, l : Integer;
pc : PChar;
begin
l := Length (search);
if l = 1 then
begin
pc := AnsiStrScan (PChar (s), search [1]);
if pc = nil then
p := 0
else
p := Integer (pc) - Integer (PChar (s)) + 1
end
else
p := Pos (search, s);
if p > 0 then
begin
result := Trim (Copy (s, 1, p - 1));
s := Trim (Copy (s, p + l, maxInt))
end
else
result := ''
end;
(*----------------------------------------------------------------------*
| function SplitString : string |
| |
| Search for a substring. If the substring is found, return the |
| characters up to the substring, and set the soure string to the |
| characters after it. If it was not found, return the entire source |
| string, and set the source string to an empty string |
*----------------------------------------------------------------------*)
function SplitString (const search : string; var s : string) : string;
var
p, l : Integer;
pc : PChar;
begin
l := Length (search);
if l = 1 then
begin
pc := AnsiStrScan (PChar (s), search [1]);
if pc = nil then
p := 0
else
p := Integer (pc) - Integer (PChar (s)) + 1
end
else
p := Pos (search, s);
if p > 0 then
begin
result := Trim (Copy (s, 1, p - 1));
s := Trim (Copy (s, p + l, maxInt))
end
else
begin
result := Trim (s);
s := ''
end
end;
function SplitToken (var st : string) : string;
var
p, p1 : Integer;
begin
p := Pos (' ', st);
p1 := Pos (#9, st);
if p = 0 then p := MaxInt;
if p1 = 0 then p1 := MaxInt;
if p < p1 then
result := SplitString (' ', st)
else
result := SplitString (#9, st)
end;
function WideStrScan(const Str: PWideChar; Chr: WideChar): PWideChar;
begin
Result := Str;
while Result^ <> Chr do
begin
if Result^ = #0 then
begin
Result := nil;
Exit;
end;
Inc(Result);
end;
end;
function WideSplitString (const search : WideString; var s : WideString) : WideString;
var
p, l : Integer;
pc : PWideChar;
begin
l := Length (search);
if l = 1 then
begin
pc := WideStrScan (PWideChar (s), search [1]);
if pc = nil then
p := 0
else
p := (Integer (pc) - Integer (PWideChar (s))) div sizeof (WideChar) + 1
end
else
p := Pos (search, s);
if p > 0 then
begin
result := Trim (Copy (s, 1, p - 1));
s := Trim (Copy (s, p + l, maxInt))
end
else
begin
result := Trim (s);
s := ''
end
end;
function WildContains (const a, b : string) : boolean;
var
p, offs, l, l1 : Integer;
begin
l := Length (a);
l1 := Length (b);
if (l1 = 0) or (l = 0) then
begin
result := False;
Exit
end;
if b [l1] = '*' then
begin
if l1 = 1 then
result := True
else
result := AnsiContainsStr (a, Copy (b, 1, l1 - 1));
exit
end;
if b [1] = '*' then
begin
result := AnsiContainsStr (a, Copy (b, 2, l1 - 1));
exit
end;
offs := 1;
repeat
p := PosEx (b, a, offs);
offs := 0;
if p > 0 then
begin
if (p > 1) and (a [p - 1] in ['A'..'Z', '0'..'9']) then
begin
offs := p + 1;
p := 0;
continue
end;
if ((p + l1) < l) and (a [p + l1] in ['A'..'Z', '0'..'9']) then
begin
offs := p + l1 + 1;
p := 0;
continue
end
end
until (p <> 0) or (offs = 0);
result := p <> 0
end;
function WWildContains (const a, b : WideString) : boolean;
var
p, offs, l, l1 : Integer;
begin
l := Length (a);
l1 := Length (b);
if (l1 = 0) or (l = 0) then
begin
result := False;
Exit
end;
if b [l1] = '*' then
begin
result := WideContainsStr (a, Copy (b, 1, l1 - 1));
exit
end;
offs := 1;
repeat
p := WidePosEx (b, a, offs);
offs := 0;
if p > 0 then
begin
if (p > 1) and IsWideCharAlNum (a [p - 1]) then
begin
offs := p + 1;
p := 0;
continue
end;
if ((p + l1) < l) and IsWideCharAlNum (a [p + l1]) then
begin
offs := p + l1 + 1;
p := 0;
continue
end
end
until (p <> 0) or (offs = 0);
result := p <> 0
end;
{ TStringSearcher }
constructor TStringSearcher.Create(const ASearchString: string; ACaseSensitive : boolean);
begin
fCaseSensitive := ACaseSensitive;
fSearchString := ASearchString;
Parse (ASearchString)
end;
function TStringSearcher.Matches(AString: string): boolean;
type
TMatch = (mYes, mNo, mMaybe);
var
i : Integer;
ok : TMatch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -