Hola Tengo una colección de objetos de tipo de nombre y quiero realizar una búsqueda de comodín en él. Por ejemplo, si proporciono un Criterio de búsqueda *ABC
, el nombre devuelto debería comenzar con ABC
. Si proporciono un Criterio de búsqueda ABC*
, el nombre devuelto debe terminar con ABC
. Si proporciono un Criterio de búsqueda *ABC*
, el nombre devuelto debe contener ABC
. Si proporciono un Criterio de búsqueda ?ABC
, el segundo, tercer y cuarto caracteres del nombre retornado deberían ser ABC
, respectivamente, y el primer carácter puede ser cualquier carácter.búsqueda de LINQ usando caracteres WildCards como *,% ,?
Respuesta
Aquí es un método de extensión puede utilizar
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("\\?", ".") + "$";
}
}
utilizarlo como sigue:
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 tomado de CodeProject)
Su método Regex (que copió y escribí desde la parte superior de mi cabeza) es mejor que el mío. – ErikHeemskerk
@ErikHeemskerk: ¿por qué molestarse en aprender la sintaxis de RegEx cuando tienes google? :-) –
creo que es necesario utilizar .Contains, .StartWith, .EndsWith
creo que es necesario Regex.Escape y 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("\\?", ".") + "$";
}
Nota: Samuel Jack's answer fue mejor en que su expresión regular era mejor, tan vergonzosamente fijado aquí.
¡Derrotame por 38 segundos, +1! –
Ah, pero de todos modos fue en vano, porque Samuel Jack publicó un método mejor para traducir la expresión comodín a una expresión regular; el mío no funciona correctamente – ErikHeemskerk
Este article listas de un método de extensión, que también es compatible con Entity Framework y LINQ-to-entities.
Ejemplo de uso: Código
var searchTerm = "*Inc";
var q = db.Customers
.WhereLike(c => c.CompanyName, searchTerm, '*')
.ToList();
Fuente:
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 });
}
}
- 1. java Runtime.getRunTime(). Exec & wildcards?
- 2. Búsqueda de comodín para LINQ
- 3. MySQL Wildcards * y%
- 4. Lucene Búsqueda de caracteres japoneses
- 5. F # String Pattern-Matching with Wildcards
- 6. Google usando caracteres no alfanuméricos
- 7. JPA - Criterios de consulta - Búsqueda de enteros usando "como"
- 8. Optimización de búsqueda de MySQL usando "como" comodines y
- 9. Búsqueda de SQLite FTS4 con caracteres especiales
- 10. palabras búsqueda de cualquiera caracteres repetidos
- 11. LINQ Convertir de IGrouping a la búsqueda
- 12. búsqueda de texto completo en LINQ
- 13. Página de búsqueda con MVC + Linq + EF
- 14. Múltiples parámetros de búsqueda con LINQ
- 15. traducción de caracteres usando Python (como el comando tr)
- 16. búsqueda de window.location.search como JSON
- 17. ¿Cómo obtengo la lista de identificadores como int usando LINQ
- 18. Búsqueda de control recursivo con LINQ
- 19. etiquetas de búsqueda como stackoverflow?
- 20. Zend Lucene búsqueda y caracteres acentuados
- 21. ¿Cómo incluir CData usando LINQ to XML?
- 22. Indexeddb: búsqueda usando comodines
- 23. Botón de búsqueda dentro del cuadro de búsqueda como Bing
- 24. Colección de cadena usando LINQ
- 25. Clasificación topológica usando LINQ
- 26. caracteres de imprenta como enteros
- 27. Query JSON usando LINQ
- 28. búsqueda de cadenas usando OQL
- 29. búsqueda de caracteres en el lenguaje de la secuencia C
- 30. Cassandra búsqueda de texto completo como
¿Estamos hablando LINQ a objetos aquí, o LINQ to SQL? –
@Samuel: Parece LINQ-to-Objects, ya que él menciona que tiene una "colección [...] de objetos". – ErikHeemskerk