Glinkot
Glinkot

Reputation: 2964

c# Regex matches too generous

I need to confirm the format of a customer number, which needs to be the format of #####-## (# being a 0-9 digit and the dash being a literal dash).

I built the regex using RegexBuddy (which lets you type in test strings to ensure it is right). I ended up with:

\d{5}-\d{2}

This tests well, giving me the desired outcomes - a 'hit' on:

12345-01

and no match for

12345

This tool provides the code to use this regex in various languages - I want to use this in C# to return true for a match against the entire string. This gives me the below, which I have put into code.

Regex.IsMatch(c.Bill_To, @"\A\d{5}-\d{2}\Z")

This code however returns my 12345 as a match!

Have I done something wrong?

Upvotes: 2

Views: 183

Answers (2)

arcain
arcain

Reputation: 15270

I think I see the issue your are having. If one of your customer numbers is in a string along with additional content, then the pattern you have isn't working. Specifying both \A and \Z means your customer number must start at the beginning of the string and end at the end of the string in order to be matched. \A is like ^ which matches the beginning of a string, and \Z is like $ which matches the end of a string -- except that they ignore whether the MultiLine option was specified.

Try using this pattern: \b\d{5}-\d{2}\b

It will only match your customer numbers if they are on a boundary between alphanumeric and non-alphanumeric characters. That also means you can find customer numbers even if they aren't separated by just whitespace as shown in the last test case in the following LINQPad script.

const string pattern = @"\b\d{5}-\d{2}\b";

Regex.IsMatch("12345", pattern).Dump(); // no match
Regex.IsMatch("12345-12", pattern).Dump(); // match
Regex.IsMatch("12345-1234", pattern).Dump(); // no match
Regex.IsMatch("word 12345 word", pattern).Dump(); // no match
Regex.IsMatch("word 12345-12 word", pattern).Dump(); // match
Regex.IsMatch("word 12345-1234 word", pattern).Dump(); // no match
Regex.IsMatch("word@12345-12@word", pattern).Dump(); // match

Upvotes: 0

Jason De Oliveira
Jason De Oliveira

Reputation: 1742

Your RegEx works correctly. Try checking the c.Bill_To value.

        bool testResult;

        var testSuccess = "12345-01";
        testResult = Regex.IsMatch(testSuccess, @"\A\d{5}-\d{2}\Z"); //is True

        var testFail = "12345";
        testResult = Regex.IsMatch(testFail, @"\A\d{5}-\d{2}\Z"); //is False

Upvotes: 1

Related Questions