⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unitsearchstring.pas

📁 Delphi的另一款钢琴软件
💻 PAS
📖 第 1 页 / 共 2 页
字号:
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 + -