C语言通配符匹配、文件名通配符匹配算法(wildchar.c)

来源:互联网 发布:vscode前端插件 编辑:程序博客网 时间:2024/06/05 01:14
 

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

源码及示例可在我的资源库中下载

 


 

原创粉丝点击