这段代码将模拟Sql LIKE的行为和语法。您可以将它包装成自己的lambda或扩展方法,以在Linq语句中使用:
public static bool IsSqlLikeMatch(string input, string pattern)
{
pattern = Regex.Escape(pattern);
pattern = pattern.Replace("%", ".*?").Replace("_", ".");
pattern = pattern.Replace(@"\[", "[").Replace(@"\]", "]").Replace(@"\^", "^");
return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase);
}
一个草率地拼凑而成的扩展方法,可以像
IEnumerable<T>.Where
方法一样工作:
public static IEnumerable<T> Like<T>(this IEnumerable<T> source, Func<T, string> selector, string pattern)
{
return source.Where(t => IsSqlLikeMatch(selector(t), pattern));
}
这将使您能够像这样格式化您的语句:
string pattern = "%ine%e";
var res = list.Like(s => s, pattern);
编辑
如果有人想使用这个代码,可以采用改进后的实现。它只需要将正则表达式转换和编译一次,而不是为每个项都进行一次转换。上面从LIKE到正则表达式的转换存在一些错误。
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();
builder.Append("^").Append(Regex.Escape(pattern)).Append("$");
builder.Replace("%", ".*").Replace("_", ".");
builder.Replace(@"\[", "[").Replace(@"\]", "]").Replace(@"\^", "^");
builder.Replace("[.*]", "[%]").Replace("[.]", "[_]");
return builder.ToString();
}
}