Salut J'ai une collection d'objets de type nom et je veux y effectuer une recherche par caractère générique. Par exemple, si je fournis un critère de recherche *ABC
, le nom renvoyé doit commencer par ABC
. Si je fournis un critère de recherche ABC*
, le nom retourné doit se terminer par ABC
. Si je fournis un critère de recherche *ABC*
, le nom renvoyé doit contenir ABC
. Si je fournis un critère de recherche ?ABC
, les deuxième, troisième et quatrième caractères renvoyés doivent être respectivement ABC
et le premier caractère peut être n'importe quel caractère.La recherche LINQ utilisant le caractère WildCards comme *,% ,?
Répondre
est ici une méthode d'extension, vous pouvez utiliser
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("\\?", ".") + "$";
}
}
utiliser comme suit:
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 pris de CodeProject)
Votre méthode Regex (que vous avez copiée et j'ai tapée du haut de ma tête) est meilleure que la mienne. – ErikHeemskerk
@ErikHeemskerk - Pourquoi apprendre la syntaxe RegEx quand vous avez google? :-) –
Je pense que vous devez utiliser .Contains, .StartWith, .EndsWith
Je pense que vous avez besoin Regex.Escape et 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("\\?", ".") + "$";
}
Note: Samuel Jack's answer était mieux que son Regex valait mieux, si honteusement fixé ici.
Battez-moi de 38 secondes, +1! –
Ah, mais c'était en vain parce que Samuel Jack a posté une meilleure méthode pour traduire l'expression générique en une regex; le mien ne fonctionne pas correctement. – ErikHeemskerk
Cette article listes une méthode d'extension qui est également compatible avec Entity Framework et LINQ-to-entities.
Exemple d'utilisation:
var searchTerm = "*Inc";
var q = db.Customers
.WhereLike(c => c.CompanyName, searchTerm, '*')
.ToList();
code source:
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. LINQ to SQL Wildcards
- 2. Java Generics (Wildcards)
- 3. Wildcards Prolog
- 4. java Runtime.getRunTime(). Exec & wildcards?
- 5. Recherche par lettres en utilisant LINQ
- 6. MySQL Wildcards * et%
- 7. problème de caractère U + 02BB dans le serveur SQL comme la recherche
- 8. Wildcards à typeid
- 9. Recherche/Filtrage ASP ListView utilisant LINQ
- 10. Les moteurs de recherche et le caractère '&'
- 11. XPath wildcards sur le nom de noeud
- 12. IMAP Recherche avec « caractère
- 13. que signifie # caractère dans la recherche JNDI?
- 14. linq recherche de caractères français
- 15. MySQL Rechercher et remplacer avec WILDCARDS - Requête
- 16. regex: caractère de recherche toujours pas parfait
- 17. Traiter un caractère Unicode plus diacritique comme un seul caractère?
- 18. mysql COMME = recherche imprécise
- 19. Recherche Technique dans SQL (comme, Contenir)
- 20. MySQL texte intégral Recherche, augmenter le caractère minimum
- 21. C Programmation: EOF comme caractère
- 22. Recherche XDocument simple LINQ
- 23. RowFilter incluant [caractère dans la chaîne de recherche
- 24. Comment enregistrer la recherche, choisissez une recherche récente, puis remplissez le formulaire en utilisant jQuery et/ou asp.net comme Priceline
- 25. C# + Recherche XML avec LINQ
- 26. Recherche avec des mots d'un caractère (MySQL)
- 27. Recherche avec Linq
- 28. Recherche du caractère le plus fréquent dans une chaîne
- 29. Comment implémenter une recherche comme la recherche d'adresse google maps?
- 30. La recherche LINQ ne permet que l'équivalence
que nous parlons LINQ à des objets ici ou LINQ to SQL? –
@Samuel: On dirait que LINQ-to-Objects, comme il le mentionne, a une 'collection d'objets'. – ErikHeemskerk