分享

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

 quasiceo 2012-12-29

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

近日在和朋友讨论MaskMatch时偶得2个不错的算法。
  函数1只支持'*','?'模糊匹配。速度比采用递归算法的快近2倍,比TMask方法快很多。
  函数2完全支持正规表达式。速度于之前的相同。(不会正规表达式的朋友慎用)
  
  
  //===========================
  //Funtion1
  //===========================
  
  //Checkifthestringcanmatchthewildcard.Itcanbeusedforunicodestringsaswell!
  //C:2004-07-24|M:2004-07-24
  functionMaskMatch(constaPattern,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//ohnevorangegangenes"*"
  casePatternPtr^of
  #0:begin
  Result:=StringPtr^=#0;
  ifResultor(StringRes=nil)or(PatternRes=nil)thenExit;
  StringPtr:=StringRes;
  PatternPtr:=PatternRes;
  Break;
  end;
  '*':begin
  Inc(PatternPtr);
  PatternRes:=PatternPtr;
  Break;
  end;
  '?':begin
  ifStringPtr^=#0thenExit;
  Inc(StringPtr);
  Inc(PatternPtr);
  end;
  elsebegin
  ifStringPtr^=#0thenExit;
  ifStringPtr^<>PatternPtr^then
  begin
  if(StringRes=nil)or(PatternRes=nil)thenExit;
  StringPtr:=StringRes;
  PatternPtr:=PatternRes;
  Break;
  endelse
  begin
  Inc(StringPtr);
  Inc(PatternPtr);
  end;
  end;
  end;
  untilFalse;
  
  repeat//mitvorangegangenem"*"
  casePatternPtr^of
  #0:begin
  Result:=True;
  Exit;
  end;
  '*':begin
  Inc(PatternPtr);
  PatternRes:=PatternPtr;
  end;
  '?':begin
  ifStringPtr^=#0thenExit;
  Inc(StringPtr);
  Inc(PatternPtr);
  end;
  elsebegin
  repeat
  ifStringPtr^=#0thenExit;
  ifStringPtr^=PatternPtr^thenBreak;
  Inc(StringPtr);
  untilFalse;
  Inc(StringPtr);
  StringRes:=StringPtr;
  Inc(PatternPtr);
  Break;
  end;
  end;
  untilFalse;
  untilFalse;
  end;
  
  
  //===========================
  //Funtion2
  //===========================
  
  function_MatchPattern(aPattern,aSource:PChar):Boolean;
  begin
  Result:=True;
  while(True)do
  begin
  caseaPattern[0]of
  #0:begin
  //Endofpatternreached.
  Result:=(aSource[0]=#0);//TRUEifendofaSource.
  Exit;
  end;
  
  '*':begin//Matchzeroormoreoccurancesofanychar.
  if(aPattern[1]=#0)then
  begin
  //Matchanynumberoftrailingchars.
  Result:=True;
  Exit;
  endelse
  Inc(aPattern);
  
  while(aSource[0]<>#0)do
  begin
  //TrytomatchanysubstringofaSource.
  if(_MatchPattern(aSource,aPattern))then
  begin
  Result:=True;
  Exit;
  end;
  
  //Continuetestingnextchar...
  Inc(aSource);
  end;
  end;
  
  '?':begin//Matchanyonechar.
  if(aSource[0]=#0)then
  begin
  Result:=False;
  Exit;
  end;
  
  //Continuetestingnextchar...
  Inc(aSource);
  Inc(aPattern);
  end;
  
  '[':begin//Matchgivensetofchars.
  if(aPattern[1]in[#0,'[',']'])then
  begin
  //InvalidSet-Sonomatch.
  Result:=False;
  Exit;
  end;
  
  if(aPattern[1]='^')then
  begin
  //Matchforexclusionofgivenset...
  Inc(aPattern,2);
  Result:=True;
  while(aPattern[0]<>']')do
  begin
  if(aPattern[1]='-')then
  begin
  //Matchcharexclusionrange.
  if(aSource[0]>=aPattern[0])and(aSource[0]<=aPattern[2])then
  begin
  //Givencharfailedsetexclusionrange.
  Result:=False;
  Break;
  endelse
  Inc(aPattern,3);
  endelse
  begin
  //Matchindividualcharexclusion.
  if(aSource[0]=aPattern[0])then
  begin
  //Givencharfailedsetelementexclusion.
  Result:=False;
  Break;
  endelse
  Inc(aPattern);
  end;
  end;
  endelse
  begin
  //Matchforinclusionofgivenset...
  Inc(aPattern);
  Result:=False;
  while(aPattern[0]<>']')do
  begin
  if(aPattern[1]='-')then
  begin
  //Matchcharinclusionrange.
  if(aSource[0]>=aPattern[0])and(aSource[0]<=aPattern[2])then
  begin
  //Givencharmatchedsetrangeinclusion.
  //Continuetesting...
  Result:=True;
  Break;
  endelse
  Inc(aPattern,3);
  endelse
  begin
  //Matchindividualcharinclusion.
  if(aSource[0]=aPattern[0])then
  begin
  //Givencharmatchedsetelementinclusion.
  //Continuetesting...
  Result:=True;
  Break;
  endelse
  Inc(aPattern);
  end;
  end;
  end;
  
  if(Result)then
  begin
  //Matchwasfound.Continuefurther.
  Inc(aSource);
  //PositionPatterntocharafter"]"
  while(aPattern[0]<>']')and(aPattern[0]<>#0)doInc(aPattern);
  if(aPattern[0]=#0)then
  begin
  //InvalidPattern-missing"]"
  Result:=False;
  Exit;
  endelse
  Inc(aPattern);
  endelse
  Exit;
  end;
  
  elsebegin//Matchgivensinglechar.
  if(aSource[0]<>aPattern[0])then
  begin
  Result:=False;
  Break;
  end;
  
  //Continuetestingnextchar...
  Inc(aSource);
  Inc(aPattern);
  end;
  end;
  end;
  end;
  
  functionMatchPattern(constaPattern,aSource:string):Boolean;
  begin
  Result:=_MatchPattern(PChar(aPattern),PChar(aSource));
  end;

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多