This snippet will mimic the behavior and syntax of Sql LIKE. You can wrap it up into a lambda or extension method of your own for use within a Linq statement:
public static bool IsSqlLikeMatch(string input, string pattern)
{
/* Turn "off" all regular expression related syntax in
* the pattern string. */
pattern = Regex.Escape(pattern);
/* Replace the SQL LIKE wildcard metacharacters with the
* equivalent regular expression metacharacters. */
pattern = pattern.Replace("%", ".*?").Replace("_", ".");
/* The previous call to Regex.Escape actually turned off
* too many metacharacters, i.e. those which are recognized by
* both the regular expression engine and the SQL LIKE
* statement ([...] and [^...]). Those metacharacters have
* to be manually unescaped here. */
pattern = pattern.Replace(@"\[", "[").Replace(@"\]", "]").Replace(@"\^", "^");
return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase);
}
A roughed together extension method that would work like IEnumerable<T>.Where
method:
public static IEnumerable<T> Like<T>(this IEnumerable<T> source, Func<T, string> selector, string pattern)
{
return source.Where(t => IsSqlLikeMatch(selector(t), pattern));
}
Which would in turn allow you to format your statement like so:
string pattern = "%ine%e";
var res = list.Like(s => s, pattern);
EDIT
An improved implementation, should anyone stumble upon and want to use this code. It converts and compiles the regex once instead for each item and the conversion from LIKE to regex above has some bugs.
public static class LikeExtension
{
public static IEnumerable<T> Like<T>(this IEnumerable<T> source, Func<T, string> selector, string pattern)
{
var regex = new Regex(ConvertLikeToRegex(pattern), RegexOptions.IgnoreCase);
return source.Where(t => IsRegexMatch(selector(t), regex));
}
static bool IsRegexMatch(string input, Regex regex)
{
if (input == null)
return false;
return regex.IsMatch(input);
}
static string ConvertLikeToRegex(string pattern)
{
StringBuilder builder = new StringBuilder();
// Turn "off" all regular expression related syntax in the pattern string
// and add regex begining of and end of line tokens so '%abc' and 'abc%' work as expected
builder.Append("^").Append(Regex.Escape(pattern)).Append("$");
/* Replace the SQL LIKE wildcard metacharacters with the
* equivalent regular expression metacharacters. */
builder.Replace("%", ".*").Replace("_", ".");
/* The previous call to Regex.Escape actually turned off
* too many metacharacters, i.e. those which are recognized by
* both the regular expression engine and the SQL LIKE
* statement ([...] and [^...]). Those metacharacters have
* to be manually unescaped here. */
builder.Replace(@"\[", "[").Replace(@"\]", "]").Replace(@"\^", "^");
// put SQL LIKE wildcard literals back
builder.Replace("[.*]", "[%]").Replace("[.]", "[_]");
return builder.ToString();
}
}