您好我有一个名称类型对象的集合,我想对它进行通配符搜索。例如,如果我提供搜索条件*ABC
,则返回的名称应以ABC
开头。如果我提供搜索条件ABC*
,则返回的名称应以ABC
结尾。如果我提供搜索条件*ABC*
,则返回的名称应包含ABC
。如果我提供搜索条件?ABC
,则返回的名称的第二个,第三个和第四个字符应分别为ABC
,第一个字符可以是任何字符。
答案 0 :(得分:10)
这是您可能使用的扩展方法
public static class EnumerableExtensions
{
public static IEnumerable<T> MatchesWildcard<T>(this IEnumerable<T> sequence, Func<T,string> expression, string pattern)
{
var regEx = WildcardToRegex(pattern);
return sequence.Where(item => Regex.IsMatch(expression(item), regEx));
}
public static string WildcardToRegex(string pattern)
{
return "^" + Regex.Escape(pattern).
Replace("\\*", ".*").
Replace("\\?", ".") + "$";
}
}
按如下方式使用:
void Main()
{
var items = new[] { new MyObj { MyProperty = "ABC123" },
new MyObj { MyProperty = "123ABC" },
new MyObj { MyProperty = "123ABC456" },
};
var matches = items.MatchesWildcard(item => item.MyProperty, "???ABC");
}
public class MyObj
{
public string MyProperty {get;set;}
}
(WildcardToRegex取自CodeProject)
答案 1 :(得分:3)
我认为你需要Regex.Escape和Regex.IsMatch()。
private IEnumerable<Item> FilterList(IEnumerable<Item> list, string query)
{
string pattern = QueryToRegex(query);
return list.Where(i => Regex.IsMatch(i.Name, pattern, RegexOptions.Singleline));
}
private static string QueryToRegex(string query)
{
return "^" + Regex.Escape(query).Replace("\\*", ".*").Replace("\\?", ".") + "$";
}
注意:Samuel Jack's answer更好,因为他的正则表达式更好,所以在这里可耻地修复它。
答案 2 :(得分:0)
我认为你需要使用.Contains,.StartWith,.EndsWith
答案 3 :(得分:0)
此article列出了一个与Entity Framework和LINQ-to-entities兼容的扩展方法。
使用示例:
var searchTerm = "*Inc";
var q = db.Customers
.WhereLike(c => c.CompanyName, searchTerm, '*')
.ToList();
源代码:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
public static class LinqExtensions
{
public static IQueryable<TSource> WhereLike<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, string>> valueSelector,
string value,
char wildcard)
{
return source.Where(BuildLikeExpression(valueSelector, value, wildcard));
}
public static Expression<Func<TElement, bool>> BuildLikeExpression<TElement>(
Expression<Func<TElement, string>> valueSelector,
string value,
char wildcard)
{
if (valueSelector == null)
throw new ArgumentNullException("valueSelector");
var method = GetLikeMethod(value, wildcard);
value = value.Trim(wildcard);
var body = Expression.Call(valueSelector.Body, method, Expression.Constant(value));
var parameter = valueSelector.Parameters.Single();
return Expression.Lambda<Func<TElement, bool>>(body, parameter);
}
private static MethodInfo GetLikeMethod(string value, char wildcard)
{
var methodName = "Contains";
var textLength = value.Length;
value = value.TrimEnd(wildcard);
if (textLength > value.Length)
{
methodName = "StartsWith";
textLength = value.Length;
}
value = value.TrimStart(wildcard);
if (textLength > value.Length)
{
methodName = (methodName == "StartsWith") ? "Contains" : "EndsWith";
textLength = value.Length;
}
var stringType = typeof(string);
return stringType.GetMethod(methodName, new Type[] { stringType });
}
}