Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Use wildcard characters * and ? to compare strings

5.00/5 (1 vote)
20 Feb 2012CPOL 17K  
This is much simpler: fewer new strings created, no recursion. And it allows the caller to specify how to do a string comparison.public static boolWildcardMatch( this string Subject, string Pattern, System.StringComparison...
This is much simpler: fewer new strings created, no recursion. And it allows the caller to specify how to do a string comparison.

public static bool
WildcardMatch
(
    this string             Subject
,
    string                  Pattern
,
    System.StringComparison StringComparison
)
{
    bool result = true ;

    if ( Subject == null )
    {
        throw ( new System.ArgumentNullException ( "Subject" , "Subject must not be null" ) ) ;
    }

    if ( Pattern == null )
    {
        throw ( new System.ArgumentNullException ( "Pattern" , "Pattern must not be null" ) ) ;
    }

    int soff = 0 ; /* Where we are in the Subject  */
    int poff = 0 ; /* Where we are in the Pattern  */
    int star = 0 ; /* The number of asterisks      */
    int ques = 0 ; /* The number of question marks */

    /* Traverse the Pattern */
    while ( result && ( poff < Pattern.Length ) )
    {
        switch ( Pattern [ poff ] )
        {
            /* Count any asterisks */
            case '*' :
            {
                star++ ;

                poff++ ;

                break ;
            }

            /* Count any question marks */
            case '?' :
            {
                ques++ ;

                poff++ ;

                break ;
            }

            /* Upon finding a non-wildcard */
            default :
            {
                /* Count the number of contiguous non-wildcards */
                int plen = poff ;

                while
                (
                  ( plen < Pattern.Length )
                &&
                  ( Pattern [ plen ] != '*' )
                &&
                  ( Pattern [ plen ] != '?' )
                )
                {
                    plen++ ;
                }

                plen -= poff ;

                /* Search the Subject for a matching sequence of characters */
                int slen = Subject.IndexOf
                (
                  Pattern.Substring ( poff , plen )
                ,
                  soff
                ,
                  StringComparison
                ) - soff ;

                /* The sequence must be present and must be offset by at least the number of  */
                /* question marks and may be offet by more if there was at least one asterisk */
                result = ( star == 0 ) ? ( slen == ques ) : ( slen >= ques ) ;

                /* Prepare to find more wildcards */
                soff += slen + plen ;
                poff += plen ;
                star = 0 ;
                ques = 0 ;

                break ;
            }
        }
    }

    /* Handle any trailing wildcards */
    if ( result )
    {
        int slen = Subject.Length - soff ;

        result = ( star == 0 ) ? ( slen == ques ) : ( slen >= ques ) ;
    }

    return ( result ) ;
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)