文章目录

最近需要实现一个支持*,?通配符的字符串匹配程序,网上搜了一下都不靠谱,实际上MySQL自己有一个支持通配符的匹配函数,抽取出来共享

注意:返回0是匹配 返回1是不匹配哦

int wild_case_compare(const char _str,const char *wildstr)
{
    char wild_many='_';
    char wild_one='?';
    char wild_prefix=0; /* QQ this can potentially cause a SIGSEGV _/
    int flag;
    while (_wildstr)
    {
        while (_wildstr && *wildstr != wild_many && *wildstr != wild_one)
        {
            if (_wildstr == wild_prefix && wildstr[1])
                wildstr++;
            if (toupper(_wildstr++) !=
                toupper(_str++)) return (1);
        }
        if (! _wildstr ) return (_str != 0);
        if (_wildstr++ == wild_one)
        {
            if (! *str++) return (1);   /_ One char; skip _/
        }
        else
        {                       /_ Found '_' */
            if (!_wildstr) return (0);      /* '_' as last char: OK */
            flag=(_wildstr != wild_many && _wildstr != wild_one);
            do
            {
                if (flag)
                {
                    char cmp;
                    if ((cmp= *wildstr) == wild_prefix && wildstr[1])
                        cmp=wildstr[1];
                    cmp=toupper(cmp);
                    while (_str && toupper(_str) != cmp)
                        str++;
                    if (!_str) return (1);
                }
                if (wild_case_compare(str,wildstr) == 0) return (0);
            } while (_str++);
            return(1);
        }
    }
    return (_str != '');
}

进一步扩展一下,对于批量匹配的一个优化,例如 123;456;789 这样隔开的字符串 只对其中的一部分字符串进行匹配,但是又避免使用malloc来生成临时变量,那么就是需要传入str的length来,取截断
例如wild_case_compare_l(“123;456;789”+4 ,3 ,”4?6”) 这样的使用方式来判断 “123;456;789”中的”456”是否匹配”4?6”
wild_case_compare_l的实现如下

int wild_case_compare_l(const char _str, const size_t length ,const char *wildstr)
{
    const char_ start = str;
    char wild_many='_';
    char wild_one='?';
    char wild_prefix=0; /_ QQ this can potentially cause a SIGSEGV _/
    int flag;
    while (_wildstr)
    {
        while (_wildstr && *wildstr != wild_many && *wildstr != wild_one)
        {
            if (_wildstr == wild_prefix && wildstr[1])
                wildstr++;
            if ((size_t)(str - start) >= length) return (1);
            else if (toupper(_wildstr++) !=
                toupper(_str++)) return (1);
        }
        if (! _wildstr ) return ((size_t)(str - start) = length) return (1);
            else str++; /_ One char; skip _/
        }
        else
        {                       /_ Found '_' */
            if (!_wildstr) return (0);      /* '_' as last char: OK */
            flag=(_wildstr != wild_many && _wildstr != wild_one);
            do
            {
                if (flag)
                {
                    char cmp;
                    if ((cmp= *wildstr) == wild_prefix && wildstr[1])
                        cmp=wildstr[1];
                    cmp=toupper(cmp);
                    while ((size_t)(str - start) = length) return (1);
                }
                if (wild_case_compare_l(str,length-(str-start),wildstr)==0) return (0);
            } while (_str++);
            return(1);
        }
    }
    return ((size_t)(str-start)<length);
}
文章目录