Vb教程 Vb.net教程 Vfp教程 C/C++教程 Vc/Vc++教程 Delphi教程 Java教程 Powerbuilder
  杀毒频道 | 短信频道 | 网络电视 | 论文中心 | 学上网 | 学软件 | 网页特效 | 电脑基础 | 论坛  
  NCRE | 软考 | CET | 职称英语 | 司法考试 | 报关员 | 公务员 | CATTI | CPA考试  
  Html教程 | Css教程 | Xml教程 | Asp教程 | Asp.net | Php教程 | Jsp教程 | Linux教程 | QQ技巧  
Photoshop Illustrator ImageReady Maya教程 3D Max教程 Lightscape Coredraw教程 Authorware Autocad教程 Freehand教程
Access教程 Mysql教程 Sql server Oracle教程 Word教程 Excel教程 Powerpoint Frontpage Asp.net源码 Php源代码
Flash教程 Fireworks Dreamweaver C#教程 outlook教程 系统安装 vbscript教程 Javascript Jsp源代码 Asp源代码
您的位置:首页 >> delphi教程 >> 正文

Delphi学习:2个不错的通配符比较函数
文章来源:csdn 作者:Stanley_Xu

近日在和朋友讨论 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;


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

[返回]

编程语言 web开发 数据库 网络技术 操作系统 服务器 网页设计 图形设计 办公软件 常用软件 学电脑

Copyright© www.bianceng.cn Powered by 编程入门网 All Rights Reserved.
关于本站 | 版权声明 | 联系我们 | 友情链接 |
编程入门网 版权所有