dev like 函数 widechar 版本

发布时间 2023-11-02 14:19:48作者: Tag
function Like(p1: PChar; l1: Integer; p2: PChar; l2: Integer;
  percent_char, underline_char, escape_char: Char): Boolean; overload;
var
  c: Char;
  AEscapeFlag: Boolean;
begin
  AEscapeFlag := False;
  repeat
    Dec(l2);
    if l2 < 0 then Break;
    c := p2^;
    p2 := p2 + 1;
    if (escape_char <> #0) and not AEscapeFlag and (c = escape_char) then
    begin
      AEscapeFlag := True;
      Continue;
    end;
    if not AEscapeFlag and (c = percent_char) then
    begin
      if l2 = 0 then
      begin
        Result := True;
        Exit;
      end;
      while l1 > 0 do
      begin
        if Like(p1, l1, p2, l2, percent_char, underline_char, escape_char) then
        begin
          Result := True;
          Exit;
        end;
        p1 := p1 + 1;
        Dec(l1);
      end;
      Result := False;
      Exit;
    end;
    Dec(l1);
    if l1 < 0 then
    begin
      Result := False;
      Exit;
    end;
    if (AEscapeFlag or (c <> underline_char)) and (c <> p1^) then
    begin
      Result := False;
      Exit;
    end;
    AEscapeFlag := False;
    p1 := p1 + 1;
  until False;
  Result := l1 = 0;
end;

function Like(p1: PWideChar; l1: Integer; p2: PWideChar; l2: Integer;
  percent_char, underline_char, escape_char: WideChar): Boolean; overload;
var
  c: WideChar;
  AEscapeFlag: Boolean;
begin
  AEscapeFlag := False;
  repeat
    Dec(l2);
    if l2 < 0 then Break;
    c := p2^;
    p2 := p2 + 1;
    if (escape_char <> #0) and not AEscapeFlag and (c = escape_char) then
    begin
      AEscapeFlag := True;
      Continue;
    end;
    if not AEscapeFlag and (c = percent_char) then
    begin
      if l2 = 0 then
      begin
        Result := True;
        Exit;
      end;
      while l1 > 0 do
      begin
        if Like(p1, l1, p2, l2, percent_char, underline_char, escape_char) then
        begin
          Result := True;
          Exit;
        end;
        p1 := p1 + 1;
        Dec(l1);
      end;
      Result := False;
      Exit;
    end;
    Dec(l1);
    if l1 < 0 then
    begin
      Result := False;
      Exit;
    end;
    if (AEscapeFlag or (c <> underline_char)) and (c <> p1^) then
    begin
      Result := False;
      Exit;
    end;
    AEscapeFlag := False;
    p1 := p1 + 1;
  until False;
  Result := l1 = 0;
end;

function LikeStr(const AStr, APatternStr: string; APercent, AUnderline: Char): Boolean;
var
  vPatternStr, vStr: WideString;
  vPercent, vUnderline:WideChar;
begin
 //赋值给widechar\widestring 系统自动去转
 vPatternStr := APatternStr;
 vStr := AStr;
 vPercent := WideChar(APercent);
 vUnderline := WideChar(AUnderline);
 //没有开启启自动补全则走原来的功能
 case AutoCompleteLikeSearch of
  False: Result := Like(PChar(AStr), Length(AStr), PChar(APatternStr),
    Length(APatternStr), APercent, AUnderline, #0);
  True:
  begin
   vPatternStr := APatternStr;
   //为了适应filterRow功能不受影响,否则FilterRow会出现左右各多一个%
   if (Pos('%', APatternStr) = 0) and (Pos('_', APatternStr) = 0)then
     vPatternStr := Format('%%%s%%', [APatternStr]);
   Result := Like(PWideChar(vStr), Length(vStr), PWideChar(vPatternStr),
    Length(vPatternStr), vPercent, vUnderline, WideChar(#0));
  end;
 end;
end;

 

经过测试,在低版本DELPHI。如果对接 “纪帅", "退" 这两个是否模糊匹配是返回成功的。这个是因为低版本DELPHI 不是widechar的
所以要多写一个widechar 版本出来。
AutoCompleteLikeSearch  这个是定义的全部变量开关,要不要自动补全%% 这里不开的话,还是走原来的dev 自己的版本。
正确应该是都要走widechar版本才对