LINQ search using WildCards, such as *,% ,?

Hi I have a collection of objects of type name and I want to search on it. For example, if I provide search criteria *ABC, then the return name should begin with ABC. If I provide search criteria ABC*, then the returned name must end in ABC. If I provided the search criteria *ABC*, then the returned name should contain ABC. If I provided the search criteria ?ABC, then the return name of the second, third, and fourth characters should be, ABCrespectively, and the first character can be any character.

+5
source share
4 answers

Here you can use the extension method

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)

+10

, 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("\\?", ".") + "$";
}

: , , .

+3

I think you need to use .Contains, .StartWith, .EndsWith

0
source

This article identifies an extension method that is also compatible with the Entity Framework and LINQ-to-entity.

Usage example:

var searchTerm = "*Inc";
var q = db.Customers
        .WhereLike(c => c.CompanyName, searchTerm, '*')
        .ToList();

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 });
        }
    }
0
source

All Articles