DOS/Windows的文件名通配符,比如:*.txt,?.txt。上次介绍了一个正则表达式的方法,这次自已写一
个通配符匹配算法,一个函数就OK了(ANSI C的)。
一、算法原理
*号代表任意字符, ?号代表一个字符
int WildCharMatch(char *src, char *pattern, int ignore_case)
算法很朴素:从src, pattern中各找一个字符,如果匹配,移动到下一格。如果有*,移动任意长。
二、C语言实现
#include <ctype.h>
/** Defines and Macros */
#define MATCH 1
#define NOT_MATCH 0
/* 匹配一个字符的宏 */
#define MATCH_CHAR(c1,c2,ignore_case) ( (c1==c2) || ((ignore_case==1) &&(tolower(c1)==tolower(c2))) )
/* 通配符匹配算法
* src 字符串
* pattern 含有通配符( * 或 ? 号)的字符串
* ignore_case 是否区分大小写,1 表示不区分, 0 表示区分
*
* 返回1表示 src 匹配 pattern,返回0表示不匹配
*/
int WildCharMatch(char *src, char *pattern, int ignore_case)
{
int result;
while (*src)
{
if (*pattern == '*')
{ /* 如果 pattern 的当前字符是 '*' */
/* 如果后续有多个 '*', 跳过 */
while ((*pattern == '*') || (*pattern == '?'))
pattern++;
/* 如果 '*" 后没有字符了,则正确匹配 */
if (!*pattern) return MATCH;
/* 在 src 中查找一个与 pattern中'*"后的一个字符相同的字符*/
while (*src && (!MATCH_CHAR(*src,*pattern,ignore_case)))
src++;
/* 如果找不到,则匹配失败 */
if (!*src) return NOT_MATCH;
/* 如果找到了,匹配剩下的字符串*/
result = WildCharMatch (src, pattern, ignore_case);
/* 如果剩下的字符串匹配不上,但src后一个字符等于pattern中'*"后的一个字符 */
/* src前进一位,继续匹配 */
while ( (!result) && (*(src+1)) && MATCH_CHAR(*(src+1),*pattern,ignore_case) )
result = WildCharMatch (++src, pattern, ignore_case);
return result;
}
else
{
/* 如果pattern中当前字符不是 '*' */
/* 匹配当前字符*/
if ( MATCH_CHAR(*src,*pattern,ignore_case) || ('?' == *pattern))
{
/* src,pattern分别前进一位,继续匹配 */
return WildCharMatch (++src, ++pattern, ignore_case);
}
else
{
return NOT_MATCH;
}
}
}
/* 如果src结束了,看pattern有否结束*/
if (*pattern)
{
/* pattern没有结束*/
if ( (*pattern=='*') && (*(pattern+1)==0) ) /* 如果pattern有最后一位字符且是'*' */
return MATCH;
else
return NOT_MATCH;
}
else
return MATCH;
}
三、用法很简单:
n = WildCharMatch("Aaa.txt","*.txt",1); //返回1
printf("\nresult: %d\n",n);
n = WildCharMatch("Aaaa","a*a",1); //返回1,这个看似简单,试了别的算法,不一定行的
printf("\nresult: %d\n",n);
n = WildCharMatch("Aaaa","a*a",0); //返回0
printf("\nresult: %d\n",n);
n = WildCharMatch("ABA","a?a",1); //返回1
printf("\nresult: %d\n",n);
n = WildCharMatch("ABAd","a?a",1); //返回0
printf("\nresult: %d\n",n);
四、小结
好了,软件中就能用了,可移植的ANSI C,请在使用时声明源码来源于JoStudio。
BLOG主页: http://blog.csdn.net/c80486
源码及示例可在我的资源库中下载