0

I researched this and cannot figure out why ?! doesn't do a Not Equal in my code.

The code has this :

var policyOne = "C";
var policyTwo = "GF1";
var policyThree = "018"
string policyNumber = $"^(?!{Regex.Escape(policyOne)}){Regex.Escape(policyTwo)}{Regex.Escape(policyTwo)}$",

So while I have also tried ?!.* , I still cannot get it to recognize that the policyOne is NOT allowed to be "C"

All 3 of the variables are joined together in a sql linq where clause

I can provide more details if needed.

This is my code

string AnyStart = "XXXDEFGHI";
string AnythingMiddle = "ABCXXXGHI";
string AnyEnds = "ABCDEFZZZ";

List<string> Strings = new List<string>()
{
    AnythingMiddle,
    AnyStart,
    AnyEnds
};

string hcdpPlnCvgCD = "ABC";
string HcdpPmtFctrCd = "DEF";
string hccCpmtFctrCd = "GHI";



var patterns = new string[]{
                $"^(?!{Regex.Escape(hcdpPlnCvgCD)}){Regex.Escape(HcdpPmtFctrCd)}{Regex.Escape(hccCpmtFctrCd)}$",
                $"^{Regex.Escape(hcdpPlnCvgCD)}(?!.*{Regex.Escape(HcdpPmtFctrCd)}){Regex.Escape(hccCpmtFctrCd)}$",
                $"^{Regex.Escape(hcdpPlnCvgCD)}{Regex.Escape(HcdpPmtFctrCd)}(?!.*{Regex.Escape(hccCpmtFctrCd)})$",
            };
            
var wildcards = new List<string>();

foreach (var pattern in patterns)
{
    var matchResult = Strings.Where(s => Regex.IsMatch(s, pattern)).ToList();
    matchResult.Dump();
}

wildcards.Dump();
6
  • can you please provide more context, how are you using the regex, and give some examples of values you're comparing. Commented Sep 11, 2020 at 5:20
  • Sure, hang on @Jpsh Commented Sep 11, 2020 at 5:20
  • @Jpsh - There is the full code ( from linqpad ) Commented Sep 11, 2020 at 5:22
  • What are you trying to do? Your policyTwo does not start with policyOne. Why not just use ^{Regex.Escape(policyTwo)}{Regex.Escape(policyTwo)}$? Commented Sep 11, 2020 at 5:23
  • So other than me trying to create some simpler names... In the end the field in sql server is a collection of 3 fields together. Thus policy = policy1 + policy2 + policy3 , thus if I simply omit PolicyOne, then the looping over 1000's of records is not correct when policy1 can be ANY value except "C" for example - so thus it can be A or ABC , just not C Commented Sep 11, 2020 at 5:27

1 Answer 1

1

I'm going to suggest a few things, first you should be evaluating the 3 different patterns individually. Second it seems like a plan has some logic behind it so I propose a Plan class. Then you can use Linq to find the plans you want.

public class Plan
{
    public Plan(string planCode)
    {
        PlanCode = planCode;
        Evaluate();
    }
    
    private const string _planCoverage= "^ABC";
    private const string _planPaymentFactor= "DEF";
    private const string _planCoPaymentFactor = "GHI$";
    
    public string PlanCode { get; set; }
    public bool IsCoverage { get; set; }
    public bool IsPayment { get; set; }
    public bool IsCoPay { get; set; }
        
    private void Evaluate()
    {
        IsCoverage = Regex.IsMatch(PlanCode, _planCoverage);
        IsPayment = Regex.IsMatch(PlanCode, _planPaymentFactor);
        IsCoPay = Regex.IsMatch(PlanCode, _planCoPaymentFactor);
    }
}

using this class the following code should accomplish what you're trying to do

string anyStart = "XXXDEFGHI";
string anyMiddle = "ABCXXXGHI";
string anyEnd = "ABCDEFZZZ";

List<Plan> plans = new List<Plan>(){
    new Plan(anyStart),
    new Plan(anyMiddle),
    new Plan(anyEnd)
};
        
//what your first regex tried to accomplish
List<string>  noCoveragePlans = plans
    .Where(plan => !plan.IsCoverage && plan.IsPayment && plan.IsCoPay)
    .Select(plan => plan.PlanCode)
    .ToList();

//what your second regex tried to accomplish
List<string> noPaymentPlans = plans
    .Where(plan => plan.IsCoverage && !plan.IsPayment && plan.IsCoPay)
    .Select(plan => plan.PlanCode)
    .ToList();

//what your third regex tried to accomplish
List<string> noCoPayPlans = plans
    .Where(plan => plan.IsCoverage && plan.IsPayment && !plan.IsCoPay)
    .Select(plan => plan.PlanCode)
    .ToList();
Sign up to request clarification or add additional context in comments.

2 Comments

Oh wow, I like that. I have not tested it yet. So thoughts on performance for other answer vs. this one with million times ran per day? Also these values _planCoverage will be passed in , I want to do that initialize one time , but the values come from a json file with many segments loaded into ... and ran thus the method has a parameter of these strings so like public static void CheckPattern(string _planCoverage .... etc.. ) thoughts?
it's very subjective and really depends on what you're trying to accomplish but overall, yes class can be used on millions of records. I'd really have to know more about your specific situation to tell.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.