Wildcard string compare/search

Previous topic - Next topic

Kitty Hello

Code (glbasic) Select


LOCAL pp% = WildcardTextCompare("abcdefg", "*d*g*") // returns "3" -> where the "d" is




// case sensitive!
IMPORT int WildcardTextCompare(const char*, const char*)


INLINE
// #NEED find first non* character match
//---------------------------------------------------------------//
// This function compares text strings, one of which can have wildcards ('*').
// http://www.drdobbs.com/architecture-and-design/matching-wildcards-an-algorithm/210200888
// GF: improved version
// returns 0..x -> position of first non wildcard character
//         -1   -> no match
//---------------------------------------------------------------//
int WildcardTextCompare(
const char* pTameText,             // A string without wildcards
const char* pWildText              // A (potentially) corresponding string with wildcards
)
{
const char* pOrigTame=pTameText;
const char* pFirstMatch=NULL;
int bMatch = TRUE;
const char* pAfterLastWild = NULL; // The location after the last '*', if we've encountered one
const char* pAfterLastTame = NULL; // The location in the tame string, from which we started after last wildcard
char t, w;

// Walk the text strings one character at a time.
for(;;)
{
t = *pTameText;
w = *pWildText;

// How do you match a unique text string?
if (!t)
{
// Easy: unique up on it!
if (!w)
{
break;                                   // "x" matches "x"
}
else if (w == '*')
{
pWildText++;
continue;                           // "x*" matches "x" or "xy"
}
else if (pAfterLastTame)
{
if (!(*pAfterLastTame))
{
bMatch = FALSE;
break;
}
pTameText = pAfterLastTame++;
pWildText = pAfterLastWild;
continue;
}

bMatch = FALSE;
break;                                           // "x" doesn't match "xy"
}
else
{
if(!pFirstMatch && w==t)
pFirstMatch = pTameText;
// How do you match a tame text string?
if (t != w)
{
// The tame way: unique up on it!
if (w == '*')
{
pAfterLastWild = ++pWildText;
pAfterLastTame = pTameText;
w = *pWildText;

if (!w )
{
break;                           // "*" matches "x"
}
continue;                           // "*y" matches "xy"
}
else if (pAfterLastWild)
{
if (pAfterLastWild != pWildText)
{
pWildText = pAfterLastWild;


w = *pWildText;

if (t == w)
{
pWildText++;
}
}
pTameText++;
continue;                           // "*sip*" matches "mississippi"
}
else
{
bMatch = FALSE;
break;                                   // "x" doesn't match "y"
}
}
}

pTameText++;
pWildText++;
}

if(bMatch)
{
if(pFirstMatch)
return (int)(pFirstMatch-pOrigTame); // return position of first match
return 0; // match at first character
}
return -1; // no match
}
ENDINLINE


Ian Price

Very useful :)

Cheers Kitty
I came. I saw. I played.