Ant*_*nov 12 c# linq-to-objects sql-like
我试图LIKE在LINQ to Objects中模拟运算符.这是我的代码:
List<string> list = new List<string>();
list.Add("line one");
list.Add("line two");
list.Add("line three");
list.Add("line four");
list.Add("line five");
list.Add("line six");
list.Add("line seven");
list.Add("line eight");
list.Add("line nine");
list.Add("line ten");
string pattern = "%ine%e";
var res = from i in list
where System.Data.Linq.SqlClient.SqlMethods.Like(i, pattern)
select i;
Run Code Online (Sandbox Code Playgroud)
它没有得到我的结果,因为System.Data.Linq.SqlClient.SqlMethods.Like它只是为了翻译成SQL.
LIKE在LINQ to Objects世界中是否存在类似于sql 运算符的东西?
jvs*_*ech 18
我不知道哪一个很容易存在,但如果你熟悉正则表达式,你可以编写自己的:
using System;
using System.Text.RegularExpressions;
public static class MyExtensions
{
public static bool Like(this string s, string pattern, RegexOptions options = RegexOptions.IgnoreCase)
{
return Regex.IsMatch(s, pattern, options);
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的代码中:
string pattern = ".*ine.*e";
var res = from i in list
where i.Like(pattern)
select i;
Run Code Online (Sandbox Code Playgroud)
此代码段将模仿Sql LIKE的行为和语法.您可以将它包装到您自己的lambda或扩展方法中,以便在Linq语句中使用:
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);
}
Run Code Online (Sandbox Code Playgroud)
一个粗糙的扩展方法,可以像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));
}
Run Code Online (Sandbox Code Playgroud)
这反过来允许您格式化您的语句,如下所示:
string pattern = "%ine%e";
var res = list.Like(s => s, pattern);
Run Code Online (Sandbox Code Playgroud)
编辑 一个改进的实现,任何人都应该偶然发现并想要使用此代码.它为每个项目转换并编译一次正则表达式,并且从LIKE到regex的转换有一些错误.
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();
}
}
Run Code Online (Sandbox Code Playgroud)
您必须使用Regex作为模式,然后使用扩展方法Where迭代并查找匹配项.
所以你的代码应该像这样结束:
string pattern = @".*ine.*e$";
var res = list.Where( e => Regex.IsMatch( e, pattern));
Run Code Online (Sandbox Code Playgroud)
如果您不熟悉Regex,请阅读:
前0个或多个字符(.*)后跟ine (ine)然后是0个或更多个字符(.*)然后是e (e),e应该是字符串的结尾($)
| 归档时间: |
|
| 查看次数: |
22085 次 |
| 最近记录: |