抽取自MySQL中的通配符比较函数
文章目录
最近需要实现一个支持*,?通配符的字符串匹配程序,网上搜了一下都不靠谱,实际上MySQL自己有一个支持通配符的匹配函数,抽取出来共享
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);
}