2个不错的通配符比较函数

andychengxin

andychengxin

2016-02-19 18:25

在这个颜值当道,屌丝闪边的时代,拼不过颜值拼内涵,只有知识丰富才能提升一个人的内在气质和修养,所谓人丑就要多学习,今天图老师给大家分享2个不错的通配符比较函数,希望可以对大家能有小小的帮助。

近日在和朋友讨论 MaskMatch 时偶得2个不错的算法。
  函数1 只支持'*','?'模糊匹配。速度比采用递归算法的快近2倍,比TMask方法快很多。
  函数2 完全支持正规表达式。速度于之前的相同。(不会正规表达式的朋友慎用)

  
  
  // ===========================
  // Funtion 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;
  
  
  // ===========================
  // Funtion 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;
  
               //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;

(本文来源于图老师网站,更多请访问https://m.tulaoshi.com/bianchengyuyan/)
展开更多 50%)
分享

猜你喜欢

2个不错的通配符比较函数

编程语言 网络编程
2个不错的通配符比较函数

Delphi学习:2个不错的通配符比较函数

Delphi
Delphi学习:2个不错的通配符比较函数

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

一个不错的随机函数

ASP
一个不错的随机函数

一个比较实用的asp函数集合类(2)

ASP
一个比较实用的asp函数集合类(2)

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

js几个不错的函数 $$()

Web开发
js几个不错的函数 $$()

JS Common 2 之比较常用到的函数

Web开发
JS Common 2 之比较常用到的函数

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

Win8系统搜索不到WIFI怎么办?

Win8系统搜索不到WIFI怎么办?

三层数据库与应用程序服务器的小型介绍(Delphi&BCB)

三层数据库与应用程序服务器的小型介绍(Delphi&BCB)
下拉加载更多内容 ↓