wildcard matching with strings
-
Hi, does anyone know how to to fnd out whether a string matches a wildcard pattern? Something like int iMatch = wcmatch("??ES*H", "DOESMATCH"); There are lots of functions that use wildcards on filenames or database tables - but I didn' find anything for strings. Any ideas or sample code welcome!
-
Hi, does anyone know how to to fnd out whether a string matches a wildcard pattern? Something like int iMatch = wcmatch("??ES*H", "DOESMATCH"); There are lots of functions that use wildcards on filenames or database tables - but I didn' find anything for strings. Any ideas or sample code welcome!
Hi I don't know any existing function which can do this but it's very easy to write it yourself. Here is the fully working example: bool strmatch(char *lpszWildCard, char *lpszString) { if(lpszWildCard == NULL || lpszString == NULL) { return false; } while(*lpszWildCard != NULL && *lpszString != NULL) { if(*lpszWildCard == '?') { } else if(*lpszWildCard == '*') { ++ lpszWildCard; while(*lpszWildCard != *lpszString && *lpszString != NULL) { ++lpszString; if(*lpszWildCard == NULL || *lpszString == NULL) break; } } else if(*lpszWildCard != *lpszString) { return false; } ++ lpszString; ++ lpszWildCard; } if(*lpszString == NULL) { while(*lpszWildCard == '*') { ++lpszWildCard; } } if(*lpszWildCard == *lpszString) { return true; } return false; } Let me know if you have any problems with this code. Alex Gorev, Dundas Software. ================== The original message was: Hi,
does anyone know how to to fnd out whether a string matches a wildcard pattern? Something like
int iMatch = wcmatch("??ES*H", "DOESMATCH");
There are lots of functions that use wildcards on filenames or database tables - but I didn' find anything for strings.
Any ideas or sample code welcome! -
Hi I don't know any existing function which can do this but it's very easy to write it yourself. Here is the fully working example: bool strmatch(char *lpszWildCard, char *lpszString) { if(lpszWildCard == NULL || lpszString == NULL) { return false; } while(*lpszWildCard != NULL && *lpszString != NULL) { if(*lpszWildCard == '?') { } else if(*lpszWildCard == '*') { ++ lpszWildCard; while(*lpszWildCard != *lpszString && *lpszString != NULL) { ++lpszString; if(*lpszWildCard == NULL || *lpszString == NULL) break; } } else if(*lpszWildCard != *lpszString) { return false; } ++ lpszString; ++ lpszWildCard; } if(*lpszString == NULL) { while(*lpszWildCard == '*') { ++lpszWildCard; } } if(*lpszWildCard == *lpszString) { return true; } return false; } Let me know if you have any problems with this code. Alex Gorev, Dundas Software. ================== The original message was: Hi,
does anyone know how to to fnd out whether a string matches a wildcard pattern? Something like
int iMatch = wcmatch("??ES*H", "DOESMATCH");
There are lots of functions that use wildcards on filenames or database tables - but I didn' find anything for strings.
Any ideas or sample code welcome!Hi Alex, thanks for your code. It is ok for the most cases. But there are many cases in which strmatch() will fail: strmatch("*?s*", "doesmatch"); doesn't work, because after '*' explicit match to '?' is searched. strmatch("*to*", "doesmatchtoo"); doesn't work because '*t' finds the first 't' and compares "tchtoo" with "to*" - result: no match. Due to a bug in the '*' case, the function will return false on all wildcards, that end on '*': else if(*lpszWildCard == '*') { ++ lpszWildCard; while(*lpszWildCard!=*lpszString && *lpszString!=NULL) { ++lpszString; // this is WRONG //if(*lpszWildCard == NULL || *lpszString == NULL) // break; // must be like this: if(*lpszWildCard == NULL) return TRUE; // rest DOES match to '*'! if (*lpszString == NULL) break; } } I suppose, that a 100% solution requires recursion and is NOT so easy to realize! -- Thomas ================== The original message was: Hi
I don't know any existing function which can
do this but it's very easy to write it yourself.Here is the fully working example:
bool strmatch(char *lpszWildCard, char *lpszString)
{
if(lpszWildCard == NULL || lpszString == NULL) {
return false;
}while(*lpszWildCard != NULL && *lpszString != NULL) {
if(*lpszWildCard == '?') {
}
else if(*lpszWildCard == '*') {
++ lpszWildCard;
while(*lpszWildCard != *lpszString && *lpszString != NULL) {
++lpszString;
if(*lpszWildCard == NULL || *lpszString == NULL)
break;
}
}
else if(*lpszWildCard != *lpszString) {
return false;
}++ lpszString;
++ lpszWildCard;
}if(*lpszString == NULL) {
while(*lpszWildCard == '*') {
++lpszWildCard;
}
}if(*lpszWildCard == *lpszString) {
return true;
}return false;
}Let me know if you have any problems with this code.
Alex Gorev,
Dundas Software.==================
The original message was:Hi,
does anyone know how to to fnd out whether a string matches a wildcard pattern? Something like
int iMatch = wcmatch("??ES*H", "DOESMATCH");
There are lots of functions that use wildcards on filenames or database tables - but I didn' find anything -
Hi Alex, thanks for your code. It is ok for the most cases. But there are many cases in which strmatch() will fail: strmatch("*?s*", "doesmatch"); doesn't work, because after '*' explicit match to '?' is searched. strmatch("*to*", "doesmatchtoo"); doesn't work because '*t' finds the first 't' and compares "tchtoo" with "to*" - result: no match. Due to a bug in the '*' case, the function will return false on all wildcards, that end on '*': else if(*lpszWildCard == '*') { ++ lpszWildCard; while(*lpszWildCard!=*lpszString && *lpszString!=NULL) { ++lpszString; // this is WRONG //if(*lpszWildCard == NULL || *lpszString == NULL) // break; // must be like this: if(*lpszWildCard == NULL) return TRUE; // rest DOES match to '*'! if (*lpszString == NULL) break; } } I suppose, that a 100% solution requires recursion and is NOT so easy to realize! -- Thomas ================== The original message was: Hi
I don't know any existing function which can
do this but it's very easy to write it yourself.Here is the fully working example:
bool strmatch(char *lpszWildCard, char *lpszString)
{
if(lpszWildCard == NULL || lpszString == NULL) {
return false;
}while(*lpszWildCard != NULL && *lpszString != NULL) {
if(*lpszWildCard == '?') {
}
else if(*lpszWildCard == '*') {
++ lpszWildCard;
while(*lpszWildCard != *lpszString && *lpszString != NULL) {
++lpszString;
if(*lpszWildCard == NULL || *lpszString == NULL)
break;
}
}
else if(*lpszWildCard != *lpszString) {
return false;
}++ lpszString;
++ lpszWildCard;
}if(*lpszString == NULL) {
while(*lpszWildCard == '*') {
++lpszWildCard;
}
}if(*lpszWildCard == *lpszString) {
return true;
}return false;
}Let me know if you have any problems with this code.
Alex Gorev,
Dundas Software.==================
The original message was:Hi,
does anyone know how to to fnd out whether a string matches a wildcard pattern? Something like
int iMatch = wcmatch("??ES*H", "DOESMATCH");
There are lots of functions that use wildcards on filenames or database tables - but I didn' find anythingHi Thomas! Of course my example will not work correctly in many situations, I've spend about 5 minutes writing it and my main task was to give an idea how you can do this. If you really want to make something like this you should spend much more time coding and testing. You've mention about the recursion but I don't think it's the right place for it, the only place when you can use it is while testing for the '*' but I don't see big advantage comparing to the usual loop. So spend some time, add several IFs and WHILEs and it will work great for you. And don't try to find an existing function, it's always better to do something small like this yourself, because you can always adjust it to your own needs. Don't forget to post the results on the CodeProject and I will also took part in testing... Regards, Alex Gorev, Dundas Software. ================== The original message was: Hi Alex,
thanks for your code. It is ok for the most cases. But there are many cases in which strmatch() will fail:
strmatch("*?s*", "doesmatch");
doesn't work, because after '*' explicit match to '?' is searched.strmatch("*to*", "doesmatchtoo");
doesn't work because '*t' finds the first 't' and compares "tchtoo" with "to*" - result: no match.Due to a bug in the '*' case, the function will return false on all wildcards, that end on '*':
else if(*lpszWildCard == '*')
{
++ lpszWildCard;
while(*lpszWildCard!=*lpszString && *lpszString!=NULL)
{
++lpszString;
// this is WRONG
//if(*lpszWildCard == NULL || *lpszString == NULL)
// break;
// must be like this:
if(*lpszWildCard == NULL)
return TRUE; // rest DOES match to '*'!
if (*lpszString == NULL)
break;
}
}I suppose, that a 100% solution requires recursion and is NOT so easy to realize!
-- Thomas
==================
The original message was:Hi
I don't know any existing function which can
do this but it's very easy to write it yourself.Here is the fully working example:
bool strmatch(char *lpszWildCard, char *lpszString)
{
if(lpszWildCard == NULL || lpszString == NULL) {
return false;
}while(*lpszWildCard != NULL && *lpszString != NULL) {
if(*lpszWildCard == '?') {
}
else if(*lpszWildCard == '*') {
++ lpszWildCard;
while(*lpszWildCard != *lpszString && -
Hi Alex, thanks for your code. It is ok for the most cases. But there are many cases in which strmatch() will fail: strmatch("*?s*", "doesmatch"); doesn't work, because after '*' explicit match to '?' is searched. strmatch("*to*", "doesmatchtoo"); doesn't work because '*t' finds the first 't' and compares "tchtoo" with "to*" - result: no match. Due to a bug in the '*' case, the function will return false on all wildcards, that end on '*': else if(*lpszWildCard == '*') { ++ lpszWildCard; while(*lpszWildCard!=*lpszString && *lpszString!=NULL) { ++lpszString; // this is WRONG //if(*lpszWildCard == NULL || *lpszString == NULL) // break; // must be like this: if(*lpszWildCard == NULL) return TRUE; // rest DOES match to '*'! if (*lpszString == NULL) break; } } I suppose, that a 100% solution requires recursion and is NOT so easy to realize! -- Thomas ================== The original message was: Hi
I don't know any existing function which can
do this but it's very easy to write it yourself.Here is the fully working example:
bool strmatch(char *lpszWildCard, char *lpszString)
{
if(lpszWildCard == NULL || lpszString == NULL) {
return false;
}while(*lpszWildCard != NULL && *lpszString != NULL) {
if(*lpszWildCard == '?') {
}
else if(*lpszWildCard == '*') {
++ lpszWildCard;
while(*lpszWildCard != *lpszString && *lpszString != NULL) {
++lpszString;
if(*lpszWildCard == NULL || *lpszString == NULL)
break;
}
}
else if(*lpszWildCard != *lpszString) {
return false;
}++ lpszString;
++ lpszWildCard;
}if(*lpszString == NULL) {
while(*lpszWildCard == '*') {
++lpszWildCard;
}
}if(*lpszWildCard == *lpszString) {
return true;
}return false;
}Let me know if you have any problems with this code.
Alex Gorev,
Dundas Software.==================
The original message was:Hi,
does anyone know how to to fnd out whether a string matches a wildcard pattern? Something like
int iMatch = wcmatch("??ES*H", "DOESMATCH");
There are lots of functions that use wildcards on filenames or database tables - but I didn' find anythingHi Thomas, Try this method, maybe it will work correctly: bool strmatch(char *lpszWildCard, char *lpszString) { if (lpszWildCard == NULL || lpszString == NULL) return false; char *p; if ((p = strpbrk(lpszWildCard, "?*")) == NULL) return 0 == strcmp(lpszWildCard, lpszString); if (0 != strncmp(lpszString, lpszWildCard, p - lpszWildCard)) return false; lpszString += p - lpszWildCard; if (*p == '?') return (*lpszString != NULL) && my_strmatch(++p, ++lpszString); while (true) { while (*p == '*') ++p; if (*p == NULL) return true; if (*p != '?') break; ++lpszString; ++p; } while (true) { if ((lpszString = strchr(lpszString, *p)) == NULL) return false; if (*lpszString == NULL) return false; if (my_strmatch(p + 1, ++lpszString)) return true; } return false; } Regards, Serguei Velikevitch, Dundas Software. ================== The original message was: Hi Alex,
thanks for your code. It is ok for the most cases. But there are many cases in which strmatch() will fail:
strmatch("*?s*", "doesmatch");
doesn't work, because after '*' explicit match to '?' is searched.strmatch("*to*", "doesmatchtoo");
doesn't work because '*t' finds the first 't' and compares "tchtoo" with "to*" - result: no match.Due to a bug in the '*' case, the function will return false on all wildcards, that end on '*':
else if(*lpszWildCard == '*')
{
++ lpszWildCard;
while(*lpszWildCard!=*lpszString && *lpszString!=NULL)
{
++lpszString;
// this is WRONG
//if(*lpszWildCard == NULL || *lpszString == NULL)
// break;
// must be like this:
if(*lpszWildCard == NULL)
return TRUE; // rest DOES match to '*'!
if (*lpszString == NULL)
break;
}
}I suppose, that a 100% solution requires recursion and is NOT so easy to realize!
-- Thomas
==================
The original message was:Hi
I don't know any existing function which can
do this but it's very easy to write it yourself.Here is the fully working example:
bool strmatch(char *lpszWildCard, char *lpszString)
{
if(lpszWildCard == NULL || lpszString == NULL) {
return false;
}while(*lpszWildCard != NULL && *lpszString != NULL) {
if(*lpszWildCard == '?') {
}
else if(*lpszWildCard == '*') {
++ lpszWildCard; -
Hi, does anyone know how to to fnd out whether a string matches a wildcard pattern? Something like int iMatch = wcmatch("??ES*H", "DOESMATCH"); There are lots of functions that use wildcards on filenames or database tables - but I didn' find anything for strings. Any ideas or sample code welcome!
Regular expressions will give you what you need (and a lot more). I don't know if this site has already received classes to do that but I know there are some in CodeGuru (http://www.codeguru.com/string/index.shtml). Good luck! Alvaro
-
Hi, does anyone know how to to fnd out whether a string matches a wildcard pattern? Something like int iMatch = wcmatch("??ES*H", "DOESMATCH"); There are lots of functions that use wildcards on filenames or database tables - but I didn' find anything for strings. Any ideas or sample code welcome!
Hello everybody and thanks for all tips and code. After all I wrote my own function that serves my needs. It is capable to handle ? and * correctly - as I think. Here it is: int wcmatch(const char *pPattern, const char *pStr; const char *mystrstr(const char *pPattern, const char *pStr, int *pLen; //similiar to strstr() but: // + the search pattern ends at a '\0' or a '*'. // + '?' matches to every character != '\0' // + Return value is pointer to the first char in pStr // that belongs to the first occurence of pPattern // or NULL if not found. // // Example: mystrstr("a?c*xyz", "123456abcdefg", &len) = "abcdefg" // len==3. const char *mystrstr(const char *pPattern, const char *pStr, int *pLen) { int iMatch; const char *pStart=pStr, *pp, *ps; if (pLen) *pLen = 0; if (!pPattern || !pStr) return FALSE; for (pStart=pStr; *pStart; pStart++) { ps = pStart; pp = pPattern; iMatch = TRUE; while (iMatch) { switch (*pp) { case '*': case '\0': if (pLen) *pLen = ps - pStart; return pStart; break; case '?': if (*ps) { pp++; ps++; } else iMatch = FALSE; break; default: if (*pp == *ps) { pp++; ps++; } else iMatch = FALSE; break; } } } return FALSE; } int wcmatch(const char *pPattern, const char *pStr) { if (!pPattern || !pStr) return FALSE; int iWildcardMode = FALSE, iLen; const char *pStarMatchStart; while (*pPattern && *pStr) { switch (*pPattern) { case '?': pPattern++; pStr++; break; case '*': // Switch to wildcard-mode. Keep this mode until a // character diffrent to '?' and '*' is found. iWildcardMode = TRUE; pPattern++; break; default: if (iWildcardMode) { iWildcardMode = FALSE; if (pStarMatchStart = mystrstr(pPattern, pStr, &iLen)) { pPattern += iLen; pStr = pStarMatchStart + iLen; } else return FALSE; } else { if (*pPattern != *pStr) return FALSE; pPattern++; pStr++; } break; } } if (*pPattern == *pStr) return TRUE; if (*pPattern == '\0') { if (iWildcardMode) return TRUE; // Last char of pattern was '*' else return FALSE; // String has additional non matching chars. No match. } if (*pStr=='\0') { // This is a match, if only '*'s follow while (*pPattern == '*')