Oxyprogrammer
Oxyprogrammer

Reputation: 1263

Three digit or a character validation regex is not working

I have a legacy code base where regex validation is being done like this:

string regexString = null;
      string matchingString = null;

// Code to populate this two
if (matchingString.Equals(regex.Match(matchingString).Value))
      {
        //success code
      }
      else
      {
        //failure code    
      }

I cannot make any change in this code. But I can set the regexString by setting a particular value. Now that you know the situation, here is the problem:

I want to validate a given string for the following conditions:

  1. It can be a one digit string.
  2. It can be two digit string.
  3. It can be three digit string.
  4. It can have the value * (but then no numbers with this.)

e.g:

Valid values are: 1, 27, 453, * .

Invalid values are: 4563, 5*, 54* .

I am using the regular expression string as [0-9]{0,3}|\*. This works perfect for the numbers but failing miserably for *. Surprisingly (for me),[0-9]{3}|\* validates any three digit number (fixed length) and *. Any help will be appreciated.

Upvotes: 0

Views: 170

Answers (2)

Rawling
Rawling

Reputation: 50104

The reason your regular expression is failing is because of the way | works!

When presented with the input *, the regular expression works as follows:

  • Start at index 0
  • Can I match [0-9]{0} here? Yes!
  • Can I be greedy and match [0-9]{1} here? No!
  • I've matched the left hand side of |
  • I'm done! My first match is ""

It is NOT going "OK, I've matched zero digits, but I'd better check to see if I can match the star instead.

Thus Value is "", and your enclosing code then realises that "" != *. " and goes down the else branch.

How to fix this?

  • To be lazy, just put the * before the | and the [0-9]{0-3} after, @"\*|[0-9]{0,3}" - this makes it match the star first if it can.
  • Replace the {0,3} with {1,3} and add a second | with nothing after, @"[0-9]{1,3}|\*|" - this makes it clear that you're matching one-to-three digits OR star OR nothing.
  • (Or do a Casimir suggests and include the ^ and $, forcing the regular expression to match the whole string - this is how the regular expression should work but it makes a mockery of the containing code. Which is fair enough, the containing code is pretty terrible.)

Upvotes: 1

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89547

did you try this syntax:

string regexString = @"^(?:[0-9]{1,3}|\*)$";

or

string regexString = "^(?:[0-9]{1,3}|\\*)$";

Upvotes: 4

Related Questions