Linq wildcard and NOT condition needed for LINQ statement

Viewed 96

I was looking at some wildcard stuff for LINQ - but not having much luck

Essentially there is a for loop in which these variables will change

varFirst = "ABC" 
varSecond = "DEF"
varThird = "GHI" 

So for my wildcard search , I want to be sure varFirst and varThird match , but varSecond is the wildcard and can be anything.

I was looking at regex, but I'm having trouble trying to understand how to do this.

var x = vidaBiliy.SponsorPackage.Where(s => s.Policy == varFirst + varSecond + varThird ).FirstOrDefault()

So in looping over the data I have a query above that is concatenating those 3 variables (they are changing prior to this based on values from a loop . So in this case - I only want varFirst and varThird to be exact match ... but varSecond can be anything. I suppose the specs use *** , but that just means anything is allowed

I was looking at regEx.IsMatch(item) , but then I'm wondering how to achieve this.

Then I need another check for " do search for the NOT condition"

Am I overthinking it or don't have enough information?

2 Answers

If you need to only keep the items where the Policy property starts with varFirst and ends with varThird, you may use

.Where(s => Regex.IsMatch(s.Policy, $"^{Regex.Escape(varFirst)}.*{Regex.Escape(varThird)}$"))

This will create a regex like ^ABC.*DEF$ and will match any string starting with ABC and ending with DEF, having any 0 or more chars other than a newline in between.

If you need a partial match, remove the anchors, ^ and $.

The Regex.Escape method is required if the varFirst and varThird can contain special regex metacharacters like ( or [ that must be matched literally.

First, let's create a handy method to accept your mandatory parameters:

public static class StringUtils
{
    public static bool IsIn(this string source, params string[] values)
    {
        return values.Contains(source);
    }

    public static bool IsAny(this string source, params string[] values)
    {
        return values.Any(v => v.Contains(source)); 
    }

    public static bool WhenAll(this string source, params string[] values)
    {
        return values.All(source.Contains);
    }
}

In case if you want varFirst and varThird to exactly match with Policy:

var x = vidaBiliy.SponsorPackage.FirstOrDefault(s => 
            s.Policy.IsIn(varFirst, varThird) &&
                        Regex.IsMatch(s.Policy, varSecond));

In case if you want on of the varFirst and varThird to exactly match with Policy:

var x = vidaBiliy.SponsorPackage.FirstOrDefault(s => 
            s.Policy.IsAny(varFirst, varThird) &&
                        Regex.IsMatch(s.Policy, varSecond));

And the case when you want "ABC123GHI" (Policy) to contain "ABC" (varFirst) and "GHI" (varThird) and optionally match Regex (varSecond):

var x = vidaBiliy.SponsorPackage.FirstOrDefault(s => 
            s.Policy.WhenAll(varFirst, varThird) &&
                        Regex.IsMatch(s.Policy, varSecond));

Note: you don't need to apply Where and the FirstOrDefault but can combine them to one method.

Related