Or, use a wildcard matching function. If you're using C++ this will be helpful:
bool Matches(const std::string & pattern, const std::string & str)
{
bool result;
// base case: if the pattern is the string, then we've succeeded.
if (pattern == str)
{
return true;
}
// If the pattern is empty, then it can't match a string, hmm?
if (pattern == "")
{
return false;
}
// * : 0 or more characters
if (pattern[0] == '*')
{
// First try 0 characters... remove the star from the pattern, and use same string
result = Matches(pattern.substr(1), str);
if (str != "" && !result)
{
// ok, that didn't work... so now eat one character and continue with the star in the pattern.
result = Matches(pattern, str.substr(1));
}
return result;
}
// ? : 0 or 1 characters
else if (pattern[0] == '?')
{
// First try 0 characters... remove ?, and use same string.
result = Matches(pattern.substr(1), str);
if (str != "" && !result)
{
// ok, that didn't work... so eat the ?, eat one character, and try again.
result = Matches(pattern.substr(1), str.substr(1));
}
return result;
}
// no wildcard: just check the two characters for equality.
else if (str != "" && pattern[0] == str[0])
{
// munch a character on each and try again.
return Matches(pattern.substr(1), str.substr(1));
}
return false;
}
I haven't tested this or even looked at it for a while, so I don't 100% guarantee it, but it should do the trick. Changing it to case-insensitive is a rather easy manner.
Not to be immodest but this kind of method is much better than the somewhat hackish approach that SMAUG has. The algorithm is
not the most efficient; it could be improved e.g. by using indices for the strings, to avoid having to continuously copy them. That's fairly simple though, so I'll leave it as an exercise to the reader. :P The recursion makes it easy(ier) to read, so I leave it at that to make it as clear as possible.