我要投稿
  • 您当前的位置:57365.com -> 技术教程 -> 软件开发教程 -> Delphi教程 -> 教程内容
  • [ 收藏本页教程 ]
  • Delphi学习:2个不错的通配符比较函数Delphi教程

    教程作者:佚名    教程来源:不详   教程栏目:Delphi教程    收藏本页
     
    近日在和朋友讨论 MaskMatch 时偶得2个不错的算法。
      函数1 只支持'*','?'模糊匹配。速度比采用递归算法的快近2倍,比TMask方法快很多。
      函数2 完全支持正规表达式。速度于之前的相同。(不会正规表达式的朋友慎用)



      // ===========================
      // Function 1
      // ===========================

      // Check if the string can match the wildcard. It can be used for unicode strings as well!
      // C: 2004-07-24 | M: 2004-07-24
      function MaskMatch(const aPattern, aSource: string): Boolean;
      var
      StringPtr, PatternPtr: PChar;
      StringRes, PatternRes: PChar;
      begin
      Result := False;
      StringPtr := PChar(UpperCase(aSource));
      PatternPtr := PChar(UpperCase(aPattern));
      StringRes := nil;
      PatternRes := nil;
      repeat
      repeat // ohne vorangegangenes "*"
      case PatternPtr^ of
      #0 : begin
      Result := StringPtr^ = #0;
      if Result or (StringRes = nil) or (PatternRes = nil) then Exit;
      StringPtr := StringRes;
      PatternPtr := PatternRes;
      Break;
      end;
      '*': begin
      Inc(PatternPtr);
      PatternRes := PatternPtr;
      Break;
      end;
      '?': begin
      if StringPtr^ = #0 then Exit;
      Inc(StringPtr);
      Inc(PatternPtr);
      end;
      else begin
      if StringPtr^ = #0 then Exit;
      if StringPtr^ <> PatternPtr^ then
      begin
      if (StringRes = nil) or (PatternRes = nil) then Exit;
      StringPtr := StringRes;
      PatternPtr := PatternRes;



      Break;
      end else
      begin
      Inc(StringPtr);
      Inc(PatternPtr);
      end;
      end;
      end;
      until False;

      repeat // mit vorangegangenem "*"
      case PatternPtr^ of
      #0 : begin
      Result := True;
      Exit;
      end;
      '*': begin
      Inc(PatternPtr);
      PatternRes := PatternPtr;
      end;
      '?': begin
      if StringPtr^ = #0 then Exit;
      Inc(StringPtr);
      Inc(PatternPtr);
      end;
      else begin
      repeat
      if StringPtr^ = #0 then Exit;
      if StringPtr^ = PatternPtr^ then Break;
      Inc(StringPtr);
      until False;
      Inc(StringPtr);
      StringRes := StringPtr;
      Inc(PatternPtr);
      Break;
      end;
      end;
      until False;
      until False;
      end;



      // ===========================
      // Function 2
      // ===========================

      function _MatchPattern(aPattern, aSource: PChar): Boolean;
      begin
      Result := True;
      while (True) do
      begin
      case aPattern[0] of
      #0 : begin
      //End of pattern reached.
      Result := (aSource[0] = #0); //TRUE if end of aSource.
      Exit;
      end;

      '*': begin //Match zero or more occurances of any char.
      if (aPattern[1] = #0) then
      begin
      //Match any number of trailing chars.
      Result := True;
      Exit;
      end else
      Inc(aPattern);

      while (aSource[0] <> #0) do
      begin
      //Try to match any substring of aSource.
      if (_MatchPattern(aSource, aPattern)) then
      begin
      Result := True;
      Exit;
      end;

      //Continue testing next char...
      Inc(aSource);
      end;
      end;

      '?': begin //Match any one char.
      if (aSource[0] = #0) then
      begin
      Result := False;
      Exit;
      end;

     

    [page]

      //Continue testing next char...
      Inc(aSource);
      Inc(aPattern);
      end;

      '[': begin //Match given set of chars.
      if (aPattern[1] in [#0,'[',']']) then
      begin
      //Invalid Set - So no match.
      Result := False;
      Exit;
      end;

      if (aPattern[1] = '^') then
      begin
      //Match for exclusion of given set...
      Inc(aPattern, 2);
      Result := True;
      while (aPattern[0] <> ']') do
      begin
      if (aPattern[1] = '-') then
      begin
      //Match char exclusion range.
      if (aSource[0] >= aPattern[0]) and (aSource[0] <= aPattern[2]) then
      begin
      //Given char failed set exclusion range.
      Result := False;
      Break;
      end else
      Inc(aPattern, 3);
      end else
      begin
      //Match individual char exclusion.
      if (aSource[0] = aPattern[0]) then
      begin
      //Given char failed set element exclusion.
      Result := False;
      Break;
      end else

     




      Inc(aPattern);
      end;
      end;
      end else
      begin
      //Match for inclusion of given set...
      Inc(aPattern);
      Result := False;
      while (aPattern[0] <> ']') do
      begin
      if (aPattern[1] = '-') then
      begin
      //Match char inclusion range.
      if (aSource[0] >= aPattern[0]) and (aSource[0] <= aPattern[2]) then
      begin
      //Given char matched set range inclusion.
      // Continue testing...
      Result := True;
      Break;
      end else
      Inc(aPattern, 3);
      end else
      begin
      //Match individual char inclusion.
      if (aSource[0] = aPattern[0]) then
      begin
      //Given char matched set element inclusion.
      // Continue testing...
      Result := True;
      Break;
      end else
      Inc(aPattern);
      end;
      end;
      end;

      if (Result) then
      begin
      //Match was found. Continue further.
      Inc(aSource);
      //Position Pattern to char after "]"

     



      while (aPattern[0] <> ']') and (aPattern[0] <> #0) do Inc(aPattern);
      if (aPattern[0] = #0) then
      begin
      //Invalid Pattern - missing "]"
      Result := False;
      Exit;
      end else
      Inc(aPattern);
      end else
      Exit;
      end;

      else begin //Match given single char.
      if (aSource[0] <> aPattern[0]) then
      begin
      Result := False;
      Break;
      end;

      //Continue testing next char...
      Inc(aSource);
      Inc(aPattern);
      end;
      end;
      end;
      end;

      function MatchPattern(const aPattern, aSource: string): Boolean;
      begin
      Result := _MatchPattern(PChar(aPattern), PChar(aSource));
      end;

      

     
    我要投稿   -   广告合作   -   关于本站   -   友情连接   -   网站地图   -   联系我们   -   版权声明   -   设为首页   -   加入收藏   -   网站留言
    Copyright © 2009 - 20012 www.www.hxswjs.com All Rights Reserved.57365.com 版权所有