C# Version Of SQL LIKE

C#.NetSqlString

C# Problem Overview


Is there any way to search patterns in strings in C#?

Something like Sql LIKE would be very useful.

C# Solutions


Solution 1 - C#

Regular expressions allow for everything that LIKE allows for, and much more, but have a completely different syntax. However, since the rules for LIKE are so simple(where % means zero-or-more characters and _ means one character), and both LIKE arguments and regular expressions are expressed in strings, we can create a regular expression that takes a LIKE argument (e.g. abc_ef% *usd) and turn it into the equivalent regular expression (e.g. \Aabc.ef.* \*usd\z):

@"\A" + new Regex(@"\.|\$|\^|\{|\[|\(|\||\)|\*|\+|\?|\\").Replace(toFind, ch => @"\" + ch).Replace('_', '.').Replace("%", ".*") + @"\z"

From that we can build a Like() method:

public static class MyStringExtensions
{
  public static bool Like(this string toSearch, string toFind)
  {
    return new Regex(@"\A" + new Regex(@"\.|\$|\^|\{|\[|\(|\||\)|\*|\+|\?|\\").Replace(toFind, ch => @"\" + ch).Replace('_', '.').Replace("%", ".*") + @"\z", RegexOptions.Singleline).IsMatch(toSearch);
  }
}

And hence:

bool willBeTrue = "abcdefg".Like("abcd_fg");
bool willAlsoBeTrue = "abcdefg".Like("ab%f%");
bool willBeFalse = "abcdefghi".Like("abcd_fg");

Solution 2 - C#

There are couple of ways you can search as "LIKE" operator of SQL in C#. If you just want to know whether the pattern exists in the string variable, you can use

string value = "samplevalue";
        value.Contains("eva"); // like '%eva%'
         value.StartsWith("eva");  // like 'eva%'
        value.EndsWith("eva"); // like '%eva'

if you want to search the pattern from a list of string, you should use LINQ to Object Features.

            List<string> valuee = new List<string> { "samplevalue1", "samplevalue2", "samplevalue3" };
        List<string> contains = (List<string>) (from val in valuee
                                        where val.Contains("pattern")
                                        select val); // like '%pattern%'

        List<string> starts = (List<string>) (from val in valuee
                                      where val.StartsWith("pattern")
                                      select val);// like 'pattern%'

        List<string> ends = (List<string>) (from val in valuee                          
                                    where val.EndsWith ("pattern")
                                    select val);// like '%pattern'

Solution 3 - C#

When I ran into this on a contract, I had no other option than to have a 100% compliant TransactSQL LIKE function. Below is the result - a static function and a string extension method. I'm sure it can be optimized further, but it's pretty fast and passed my long list of test scenarios. Hope it helps someone!

using System;
using System.Collections.Generic;

namespace SqlLikeSample
{
    public class TestSqlLikeFunction
    {
        static void Main(string[] args)
        {
            TestSqlLikePattern(true, "%", "");
            TestSqlLikePattern(true, "%", " ");
            TestSqlLikePattern(true, "%", "asdfa asdf asdf");
            TestSqlLikePattern(true, "%", "%");
            TestSqlLikePattern(false, "_", "");
            TestSqlLikePattern(true, "_", " ");
            TestSqlLikePattern(true, "_", "4");
            TestSqlLikePattern(true, "_", "C");
            TestSqlLikePattern(false, "_", "CX");
            TestSqlLikePattern(false, "[ABCD]", "");
            TestSqlLikePattern(true, "[ABCD]", "A");
            TestSqlLikePattern(true, "[ABCD]", "b");
            TestSqlLikePattern(false, "[ABCD]", "X");
            TestSqlLikePattern(false, "[ABCD]", "AB");
            TestSqlLikePattern(true, "[B-D]", "C");
            TestSqlLikePattern(true, "[B-D]", "D");
            TestSqlLikePattern(false, "[B-D]", "A");
            TestSqlLikePattern(false, "[^B-D]", "C");
            TestSqlLikePattern(false, "[^B-D]", "D");
            TestSqlLikePattern(true, "[^B-D]", "A");
            TestSqlLikePattern(true, "%TEST[ABCD]XXX", "lolTESTBXXX");
            TestSqlLikePattern(false, "%TEST[ABCD]XXX", "lolTESTZXXX");
            TestSqlLikePattern(false, "%TEST[^ABCD]XXX", "lolTESTBXXX");
            TestSqlLikePattern(true, "%TEST[^ABCD]XXX", "lolTESTZXXX");
            TestSqlLikePattern(true, "%TEST[B-D]XXX", "lolTESTBXXX");
            TestSqlLikePattern(true, "%TEST[^B-D]XXX", "lolTESTZXXX");
            TestSqlLikePattern(true, "%Stuff.txt", "Stuff.txt");
            TestSqlLikePattern(true, "%Stuff.txt", "MagicStuff.txt");
            TestSqlLikePattern(false, "%Stuff.txt", "MagicStuff.txt.img");
            TestSqlLikePattern(false, "%Stuff.txt", "Stuff.txt.img");
            TestSqlLikePattern(false, "%Stuff.txt", "MagicStuff001.txt.img");
            TestSqlLikePattern(true, "Stuff.txt%", "Stuff.txt");
            TestSqlLikePattern(false, "Stuff.txt%", "MagicStuff.txt");
            TestSqlLikePattern(false, "Stuff.txt%", "MagicStuff.txt.img");
            TestSqlLikePattern(true, "Stuff.txt%", "Stuff.txt.img");
            TestSqlLikePattern(false, "Stuff.txt%", "MagicStuff001.txt.img");
            TestSqlLikePattern(true, "%Stuff.txt%", "Stuff.txt");
            TestSqlLikePattern(true, "%Stuff.txt%", "MagicStuff.txt");
            TestSqlLikePattern(true, "%Stuff.txt%", "MagicStuff.txt.img");
            TestSqlLikePattern(true, "%Stuff.txt%", "Stuff.txt.img");
            TestSqlLikePattern(false, "%Stuff.txt%", "MagicStuff001.txt.img");
            TestSqlLikePattern(true, "%Stuff%.txt", "Stuff.txt");
            TestSqlLikePattern(true, "%Stuff%.txt", "MagicStuff.txt");
            TestSqlLikePattern(false, "%Stuff%.txt", "MagicStuff.txt.img");
            TestSqlLikePattern(false, "%Stuff%.txt", "Stuff.txt.img");
            TestSqlLikePattern(false, "%Stuff%.txt", "MagicStuff001.txt.img");
            TestSqlLikePattern(true, "%Stuff%.txt", "MagicStuff001.txt");
            TestSqlLikePattern(true, "Stuff%.txt%", "Stuff.txt");
            TestSqlLikePattern(false, "Stuff%.txt%", "MagicStuff.txt");
            TestSqlLikePattern(false, "Stuff%.txt%", "MagicStuff.txt.img");
            TestSqlLikePattern(true, "Stuff%.txt%", "Stuff.txt.img");
            TestSqlLikePattern(false, "Stuff%.txt%", "MagicStuff001.txt.img");
            TestSqlLikePattern(false, "Stuff%.txt%", "MagicStuff001.txt");
            TestSqlLikePattern(true, "%Stuff%.txt%", "Stuff.txt");
            TestSqlLikePattern(true, "%Stuff%.txt%", "MagicStuff.txt");
            TestSqlLikePattern(true, "%Stuff%.txt%", "MagicStuff.txt.img");
            TestSqlLikePattern(true, "%Stuff%.txt%", "Stuff.txt.img");
            TestSqlLikePattern(true, "%Stuff%.txt%", "MagicStuff001.txt.img");
            TestSqlLikePattern(true, "%Stuff%.txt%", "MagicStuff001.txt");
            TestSqlLikePattern(true, "_Stuff_.txt_", "1Stuff3.txt4");
            TestSqlLikePattern(false, "_Stuff_.txt_", "1Stuff.txt4");
            TestSqlLikePattern(false, "_Stuff_.txt_", "1Stuff3.txt");
            TestSqlLikePattern(false, "_Stuff_.txt_", "Stuff3.txt4");
            
            Console.ReadKey();
        }

        public static void TestSqlLikePattern(bool expectedResult, string pattern, string testString)
        {
            bool result = testString.SqlLike(pattern);
            if (expectedResult != result)
            {
                Console.ForegroundColor = ConsoleColor.Red; System.Console.Out.Write("[SqlLike] FAIL");
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Green; Console.Write("[SqlLike] PASS");
            }
            Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(": \"" + testString + "\" LIKE \"" + pattern + "\" == " + expectedResult);
        }
    }

    public static class SqlLikeStringExtensions
    {
        public static bool SqlLike(this string s, string pattern)
        {
            return SqlLikeStringUtilities.SqlLike(pattern, s);
        }
    }

    public static class SqlLikeStringUtilities
    {
        public static bool SqlLike(string pattern, string str)
        {
            bool isMatch = true,
                isWildCardOn = false,
                isCharWildCardOn = false,
                isCharSetOn = false,
                isNotCharSetOn = false,
                endOfPattern = false;
            int lastWildCard = -1;
            int patternIndex = 0;
            List<char> set = new List<char>();
            char p = '\0';

            for (int i = 0; i < str.Length; i++)
            {
                char c = str[i];
                endOfPattern = (patternIndex >= pattern.Length);
                if (!endOfPattern)
                {
                    p = pattern[patternIndex];

                    if (!isWildCardOn && p == '%')
                    {
                        lastWildCard = patternIndex;
                        isWildCardOn = true;
                        while (patternIndex < pattern.Length &&
                            pattern[patternIndex] == '%')
                        {
                            patternIndex++;
                        }
                        if (patternIndex >= pattern.Length) p = '\0';
                        else p = pattern[patternIndex];
                    }
                    else if (p == '_')
                    {
                        isCharWildCardOn = true;
                        patternIndex++;
                    }
                    else if (p == '[')
                    {
                        if (pattern[++patternIndex] == '^')
                        {
                            isNotCharSetOn = true;
                            patternIndex++;
                        }
                        else isCharSetOn = true;

                        set.Clear();
                        if (pattern[patternIndex + 1] == '-' && pattern[patternIndex + 3] == ']')
                        {
                            char start = char.ToUpper(pattern[patternIndex]);
                            patternIndex += 2;
                            char end = char.ToUpper(pattern[patternIndex]);
                            if (start <= end)
                            {
                                for (char ci = start; ci <= end; ci++)
                                {
                                    set.Add(ci);
                                }
                            }
                            patternIndex++;
                        }

                        while (patternIndex < pattern.Length &&
                            pattern[patternIndex] != ']')
                        {
                            set.Add(pattern[patternIndex]);
                            patternIndex++;
                        }
                        patternIndex++;
                    }
                }

                if (isWildCardOn)
                {
                    if (char.ToUpper(c) == char.ToUpper(p))
                    {
                        isWildCardOn = false;
                        patternIndex++;
                    }
                }
                else if (isCharWildCardOn)
                {
                    isCharWildCardOn = false;
                }
                else if (isCharSetOn || isNotCharSetOn)
                {
                    bool charMatch = (set.Contains(char.ToUpper(c)));
                    if ((isNotCharSetOn && charMatch) || (isCharSetOn && !charMatch))
                    {
                        if (lastWildCard >= 0) patternIndex = lastWildCard;
                        else
                        {
                            isMatch = false;
                            break;
                        }
                    }
                    isNotCharSetOn = isCharSetOn = false;
                }
                else
                {
                    if (char.ToUpper(c) == char.ToUpper(p))
                    {
                        patternIndex++;
                    }
                    else
                    {
                        if (lastWildCard >= 0) patternIndex = lastWildCard;
                        else
                        {
                            isMatch = false;
                            break;
                        }
                    }
                }
            }
            endOfPattern = (patternIndex >= pattern.Length);

            if (isMatch && !endOfPattern)
            {
                bool isOnlyWildCards = true;
                for (int i = patternIndex; i < pattern.Length; i++)
                {
                    if (pattern[i] != '%')
                    {
                        isOnlyWildCards = false;
                        break;
                    }
                }
                if (isOnlyWildCards) endOfPattern = true;
            }
            return isMatch && endOfPattern;
        }
    }
}

Solution 4 - C#

myString.Contain("someString");  // equal with myString LIKE '%someString%'
myString.EndWith("someString");  // equal with myString LIKE '%someString'
myString.StartWith("someString");  // equal with myString LIKE 'someString%'

Solution 5 - C#

Simply .Contains() would do the work for you.

"Example String".Contains("amp");   //like '%amp%'

This would return true, and performing a select on it would return the desired output.

Solution 6 - C#

Operators.LikeString

https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.compilerservices.operators.likestring(v=vs.100).ASPX

public static bool LikeString(
	string Source,
	string Pattern,
	CompareMethod CompareOption
)

Solution 7 - C#

Have your tried

"This is a string".Contains("string");

Solution 8 - C#

Solution 9 - C#

Contains maybe

if ("bla bli blu".Contains("blu")){......}

Solution 10 - C#

Check out this question - https://stackoverflow.com/questions/835790/how-to-do-sql-like-in-linq

Also, for more advanced string pattern searching, there are lots of tutorials on using Regular Expressions - e.g. http://www.codeproject.com/KB/dotnet/regextutorial.aspx

Solution 11 - C#

I think you can use "a string.Contains("str") for this.

it will search in a string to a patern, and result true is founded and false if not.

Solution 12 - C#

As a late but proper answer:

The closest thing there is to a SQL-Like function in C-Sharp is the implementation of a SQL-Like function in C#.

You can rip it out of http://code.google.com/p/csharp-sqlite/source/checkout<br /> [root]/csharp-sqlite/Community.CsharpSqlite/src/func_c.cs

    /*
** Implementation of the like() SQL function.  This function implements
** the build-in LIKE operator.  The first argument to the function is the
** pattern and the second argument is the string.  So, the SQL statements:
**
**       A LIKE B
**
** is implemented as like(B,A).
**
** This same function (with a different compareInfo structure) computes
** the GLOB operator.
*/
    static void likeFunc(
    sqlite3_context context,
    int argc,
    sqlite3_value[] argv
    )
    {
      string zA, zB;
      u32 escape = 0;
      int nPat;
      sqlite3 db = sqlite3_context_db_handle( context );

      zB = sqlite3_value_text( argv[0] );
      zA = sqlite3_value_text( argv[1] );

      /* Limit the length of the LIKE or GLOB pattern to avoid problems
      ** of deep recursion and N*N behavior in patternCompare().
      */
      nPat = sqlite3_value_bytes( argv[0] );
      testcase( nPat == db.aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] );
      testcase( nPat == db.aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] + 1 );
      if ( nPat > db.aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] )
      {
        sqlite3_result_error( context, "LIKE or GLOB pattern too complex", -1 );
        return;
      }
      //Debug.Assert( zB == sqlite3_value_text( argv[0] ) );  /* Encoding did not change */

      if ( argc == 3 )
      {
        /* The escape character string must consist of a single UTF-8 character.
        ** Otherwise, return an error.
        */
        string zEsc = sqlite3_value_text( argv[2] );
        if ( zEsc == null )
          return;
        if ( sqlite3Utf8CharLen( zEsc, -1 ) != 1 )
        {
          sqlite3_result_error( context,
          "ESCAPE expression must be a single character", -1 );
          return;
        }
        escape = sqlite3Utf8Read( zEsc, ref zEsc );
      }
      if ( zA != null && zB != null )
      {
        compareInfo pInfo = (compareInfo)sqlite3_user_data( context );
#if SQLITE_TEST
#if !TCLSH
        sqlite3_like_count++;
#else
        sqlite3_like_count.iValue++;
#endif
#endif
        sqlite3_result_int( context, patternCompare( zB, zA, pInfo, escape ) ? 1 : 0 );
      }
    }




    /*
    ** Compare two UTF-8 strings for equality where the first string can
    ** potentially be a "glob" expression.  Return true (1) if they
    ** are the same and false (0) if they are different.
    **
    ** Globbing rules:
    **
    **      '*'       Matches any sequence of zero or more characters.
    **
    **      '?'       Matches exactly one character.
    **
    **     [...]      Matches one character from the enclosed list of
    **                characters.
    **
    **     [^...]     Matches one character not in the enclosed list.
    **
    ** With the [...] and [^...] matching, a ']' character can be included
    ** in the list by making it the first character after '[' or '^'.  A
    ** range of characters can be specified using '-'.  Example:
    ** "[a-z]" matches any single lower-case letter.  To match a '-', make
    ** it the last character in the list.
    **
    ** This routine is usually quick, but can be N**2 in the worst case.
    **
    ** Hints: to match '*' or '?', put them in "[]".  Like this:
    **
    **         abc[*]xyz        Matches "abc*xyz" only
    */
    static bool patternCompare(
    string zPattern,            /* The glob pattern */
    string zString,             /* The string to compare against the glob */
    compareInfo pInfo,          /* Information about how to do the compare */
    u32 esc                     /* The escape character */
    )
    {
      u32 c, c2;
      int invert;
      int seen;
      int matchOne = (int)pInfo.matchOne;
      int matchAll = (int)pInfo.matchAll;
      int matchSet = (int)pInfo.matchSet;
      bool noCase = pInfo.noCase;
      bool prevEscape = false;     /* True if the previous character was 'escape' */
      string inPattern = zPattern; //Entered Pattern

      while ( ( c = sqlite3Utf8Read( zPattern, ref zPattern ) ) != 0 )
      {
        if ( !prevEscape && c == matchAll )
        {
          while ( ( c = sqlite3Utf8Read( zPattern, ref zPattern ) ) == matchAll
          || c == matchOne )
          {
            if ( c == matchOne && sqlite3Utf8Read( zString, ref zString ) == 0 )
            {
              return false;
            }
          }
          if ( c == 0 )
          {
            return true;
          }
          else if ( c == esc )
          {
            c = sqlite3Utf8Read( zPattern, ref zPattern );
            if ( c == 0 )
            {
              return false;
            }
          }
          else if ( c == matchSet )
          {
            Debug.Assert( esc == 0 );         /* This is GLOB, not LIKE */
            Debug.Assert( matchSet < 0x80 );  /* '[' is a single-byte character */
            int len = 0;
            while ( len < zString.Length && patternCompare( inPattern.Substring( inPattern.Length - zPattern.Length - 1 ), zString.Substring( len ), pInfo, esc ) == false )
            {
              SQLITE_SKIP_UTF8( zString, ref len );
            }
            return len < zString.Length;
          }
          while ( ( c2 = sqlite3Utf8Read( zString, ref zString ) ) != 0 )
          {
            if ( noCase )
            {
               if( 0==((c2)&~0x7f) )
                c2 = (u32)sqlite3UpperToLower[c2]; //GlogUpperToLower(c2);
               if ( 0 == ( ( c ) & ~0x7f ) )
                 c = (u32)sqlite3UpperToLower[c]; //GlogUpperToLower(c);
              while ( c2 != 0 && c2 != c )
              {
                c2 = sqlite3Utf8Read( zString, ref zString );
                if ( 0 == ( ( c2 ) & ~0x7f ) )
                  c2 = (u32)sqlite3UpperToLower[c2]; //GlogUpperToLower(c2);
              }
            }
            else
            {
              while ( c2 != 0 && c2 != c )
              {
                c2 = sqlite3Utf8Read( zString, ref zString );
              }
            }
            if ( c2 == 0 )
              return false;
            if ( patternCompare( zPattern, zString, pInfo, esc ) )
              return true;
          }
          return false;
        }
        else if ( !prevEscape && c == matchOne )
        {
          if ( sqlite3Utf8Read( zString, ref zString ) == 0 )
          {
            return false;
          }
        }
        else if ( c == matchSet )
        {
          u32 prior_c = 0;
          Debug.Assert( esc == 0 );    /* This only occurs for GLOB, not LIKE */
          seen = 0;
          invert = 0;
          c = sqlite3Utf8Read( zString, ref zString );
          if ( c == 0 )
            return false;
          c2 = sqlite3Utf8Read( zPattern, ref zPattern );
          if ( c2 == '^' )
          {
            invert = 1;
            c2 = sqlite3Utf8Read( zPattern, ref zPattern );
          }
          if ( c2 == ']' )
          {
            if ( c == ']' )
              seen = 1;
            c2 = sqlite3Utf8Read( zPattern, ref zPattern );
          }
          while ( c2 != 0 && c2 != ']' )
          {
            if ( c2 == '-' && zPattern[0] != ']' && zPattern[0] != 0 && prior_c > 0 )
            {
              c2 = sqlite3Utf8Read( zPattern, ref zPattern );
              if ( c >= prior_c && c <= c2 )
                seen = 1;
              prior_c = 0;
            }
            else
            {
              if ( c == c2 )
              {
                seen = 1;
              }
              prior_c = c2;
            }
            c2 = sqlite3Utf8Read( zPattern, ref zPattern );
          }
          if ( c2 == 0 || ( seen ^ invert ) == 0 )
          {
            return false;
          }
        }
        else if ( esc == c && !prevEscape )
        {
          prevEscape = true;
        }
        else
        {
          c2 = sqlite3Utf8Read( zString, ref zString );
          if ( noCase )
          {
            if ( c < 0x80 )
              c = (u32)sqlite3UpperToLower[c]; //GlogUpperToLower(c);
            if ( c2 < 0x80 )
              c2 = (u32)sqlite3UpperToLower[c2]; //GlogUpperToLower(c2);
          }
          if ( c != c2 )
          {
            return false;
          }
          prevEscape = false;
        }
      }
      return zString.Length == 0;
    }

Solution 13 - C#

Use it like this:

if (lbl.Text.StartWith("hr")==true ) {…}

Solution 14 - C#

This is my implementation - it passes the tests and does the trick - you may want to change the replacement token if you're using three tildes in your statements:

private Regex LikeExpressionToRegexPattern(String likePattern)
{
    var replacementToken = "~~~";

    String result = likePattern.Replace("_", replacementToken)
        .Replace("%", ".*");

    result = Regex.Replace(result, @"\[.*" + replacementToken + @".*\]", "_");

    result = result.Replace(replacementToken, ".");

    return new Regex("^" + result + "$", RegexOptions.IgnoreCase);
}

Example:

// Define a test string.
string text = "Hello stackoverflow world";

string like = "%flow%";

// Define a regular expression and Find matches.
MatchCollection matches = LikeExpressionToRegexPattern(like).Matches(text);

//Result.
if (matches.Count > 0) {
	//Yes
} else {
	//No
}

Solution 15 - C#

public static class StringsEx
{
    public static IEnumerable<String> Like(this IEnumerable<String> input, String pattern)
    {
        var dt = new DataTable();
        dt.Columns.Add("Search");
        foreach (String str in input)
        {
            dt.Rows.Add(str);
        }
        dt.DefaultView.RowFilter = String.Format("Search LIKE '{0}'", pattern);
        return dt.DefaultView.ToTable()
            .AsEnumerable()
            .Select(r => r.Field<String>("Search"));
    }
}

The only disadvantage is following: "Wildcard characters are not allowed in the middle of a string. For example, 'te*xt' is not allowed."©

Solution 16 - C#

there are several good answers here. to summarize what is already here and correct: using contains, startswith, endswith are good answers for most needs. regular expressions are what you want for more advanced needs.

something that is not mentioned in these answers, though, is that for a collection of strings, linq can be used to apply these filters in a call to the where method.

Solution 17 - C#

Add a VB.NET DLL encapsulating the VB.NET Like Operator

Solution 18 - C#

As aready proposed in this answer and this other answer Microsoft.VisualBasic.CompilerServices.Operators.LikeString could be a good option for simple tasks, when a RegExp is overkill. Syntax is different from RegExp and SQL LIKE operator, but it's really simple to learn (mainly because it's also very limited).

Assembly Microsoft.VisualBasic must be added as a reference to the project to use this method.

For more information see Operators.LikeString Method and for a description of the syntax see Like Operator (Visual Basic).

It can be used as an extension method to String class:

/// <summary>
/// Visual Basic like operator. Performs simple, case insensitive, string pattern matching.
/// </summary>
/// <param name="thisString"></param>
/// <param name="pattern"> ? = Any single character. * = Zero or more characters. # = Any single digit (0–9)</param>
/// <returns>true if the string matches the pattern</returns>
public static bool Like(this string thisString, string pattern)
    => Microsoft.VisualBasic.CompilerServices.Operators
        .LikeString(thisString, pattern, Microsoft.VisualBasic.CompareMethod.Text);
    

Solution 19 - C#

public static bool Like(this string value, string pattern)
{
    if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(pattern))
        return false;

    bool valid = true;
    string[] words = pattern.Split("*");
    int counter = words.Count();

    for (int i = 0; i < counter; i++)
    {
        valid = valid && value.StartsWith(words[i]);                
        value = value.Substring(words[i].Length);
    }
    return valid;
 }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAhmet AltunView Question on Stackoverflow
Solution 1 - C#Jon HannaView Answer on Stackoverflow
Solution 2 - C#Foyzul KarimView Answer on Stackoverflow
Solution 3 - C#komma8.komma1View Answer on Stackoverflow
Solution 4 - C#M.R.SadeghiView Answer on Stackoverflow
Solution 5 - C#Ali Shah AhmedView Answer on Stackoverflow
Solution 6 - C#Fernando Diaz ToledanoView Answer on Stackoverflow
Solution 7 - C#Ash BurlaczenkoView Answer on Stackoverflow
Solution 8 - C#Daniel EarwickerView Answer on Stackoverflow
Solution 9 - C#GuidhouseView Answer on Stackoverflow
Solution 10 - C#StuartView Answer on Stackoverflow
Solution 11 - C#user674535View Answer on Stackoverflow
Solution 12 - C#Stefan SteigerView Answer on Stackoverflow
Solution 13 - C#chevhfghfghfghView Answer on Stackoverflow
Solution 14 - C#DavidWainwrightView Answer on Stackoverflow
Solution 15 - C#QrystaLView Answer on Stackoverflow
Solution 16 - C#Dave RaelView Answer on Stackoverflow
Solution 17 - C#Peter MeinlView Answer on Stackoverflow
Solution 18 - C#JordiView Answer on Stackoverflow
Solution 19 - C#BelkhiterView Answer on Stackoverflow