Matching strings with wildcards.

Matching strings with wildcards.

One of the extension methods available as part of the CODEGATOR CG.Core NUGET package, is a little method named IsMatch. That method accepts two strings and makes a comparison, using wildcards, returning a True if there is a match, or a False otherwise. The two wildcard symbols recognized are: a * symbol, matching everything after the *, or, a ? symbol, matching a single character.

Here is what the method itself looks like:

public static bool IsMatch(
    this string lhs,
    string rhs
    )
{
    Guard.Instance().ThrowIfNull(lhs, nameof(lhs))
        .ThrowIfNull(rhs, nameof(rhs));

    var result = false;
    if (rhs.Contains("*") || rhs.Contains("?"))
    {
        var regex = "^" + Regex.Escape(rhs).Replace("\\?", ".").Replace("\\*", ".*") + "$";
        result = Regex.IsMatch(lhs, regex);
    }
    else if (lhs.Contains("*") || lhs.Contains("?"))
    {
        var regex = "^" + Regex.Escape(lhs).Replace("\\?", ".").Replace("\\*", ".*") + "$";
        result = Regex.IsMatch(rhs, regex);
    }
    else
    {
        result = lhs.Equals(rhs);
    }
    return result;
}

The first thing I do is validate the two string parameters, specifically checking for NULL values. After that I check the right hand side of the comparison for wildcards. If it contains one or more wildcards, I replace that symbol, in the right hand string, with an equivalent symbol that will work with a regular expression. I could have used the regular expression symbols as the wild card symbols, but, I figured more people were family with ? and * as wildcards, thanks to the Operating System we all know and love. Once the wildcard symbols have been converted to a REGEX equivalent, I create a REGEX statement, on the fly, and use that to perform the actual string comparison.

Assuming the left hand side of the operation is the one with wildcards, I perform the same steps using the wild cards from the left hand side’s string value.

Assuming neither side contains any wild card characters, I just perform a standard string comparison operation and return the results.

Assuming both the left AND right hand sides contain wild card characters … Erm, I confess, I hadn’t considered that. I’ll have to go back and add a check for that … See? it pays to describe your code to other people …

I use this method all over the place. Specifically, in the CG.Collections.Generic namespace, I use this IsMatch method to drive another set of extension methods, that allow me to filter an enumerable sequence of objects using a white list, or a black list, where the lists themselves can contain strings with wild cards.

As always, all the source code for CG.Core can be found on the CODEGATOR GitHub page, HERE.

The NUGET package itself can be downloaded directly from the CODEGATOR NUGET page, HERE.

Photo by Markus Winkler on Unsplash