Zerobu
Zerobu

Reputation: 2691

Regex date matching not working

I have a problem with my regex. Here it is.

/0[1-9]|1[0-2]|^[1-9]{1}$\/^[1-9]{1}$|0[1-9]|[1-2]\d|3[0-1]\/19\d{2}|20\d{2}/

It should not match this date,

1/32/2006

but for some reason it is matching, can you tell me what I am doing wrong?

Upvotes: 1

Views: 224

Answers (5)

snoofkin
snoofkin

Reputation: 8895

There is a good overview of regular expressions matching dates here. In particular, it lists this regular expression for matching MM/DD/YYYY dates:

^(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d$

Upvotes: 0

Alan Moore
Alan Moore

Reputation: 75222

This is interesting:

^[1-9]{1}$

It looks like you're using that to match a digit that's not preceded or followed by another digit. That won't work. ^ and $ anchor the match to the beginning and end of the string, and {1} does nothing at all.

If you want to allow for a single-digit number with an optional leading zero, use this:

0?[1-9]

The full regex would then be:

(?:1[02]|0?[1-9])\/(?:3[01]|[12]\d|0?[1-9])\/(?:19\d{2}|20\d{2})

I've also added parentheses for grouping, as @Seth suggested.

Upvotes: 2

ikegami
ikegami

Reputation: 385655

Even with all the spacing and the better delimiter,

m{
    ^
    (?: 0[1-9] | 1[0-2]? | [2-9] )
    /
    (?: 0[1-9] | 1[0-9]? | 2[0-9]? | 3[0-1]? | [4-9] )
    /
    (?: (?:19|20)[0-9]{2} )
    \z
}x

is not nearly as readable as

m{ ^ ([0-9]{1,2}) / ([0-9]{1,2}) / ([0-9]{4}) \z }x
    && $1 >=    1 && $1 <=   12
    && $2 >=    1 && $2 <=   31
    && $3 >= 1900 && $3 <= 2099

I've applied some fixes:

  1. \d is not equivalent to [0-9].
  2. $ allows for a newline.
  3. I avoided needless captures (since the original didn't have them).

Upvotes: 1

Seth Robertson
Seth Robertson

Reputation: 31441

You would seem to have several problems.

The regex is matching "06" (from 2006) in the very first alternative you have listed "0[1-9]"

You probably meant

/^(0[1-9]|1[0-2]|^[1-9]{1})\/([1-9]{1}|0[1-9]|[1-2]\d|3[0-1])\/(19\d{2}|20\d{2})$/

or something like that (I have not tested that regex and it probably has other problems remaining), but you should really look at Regular Expression to match a valid day in a date to see a better regexp and words to the wise about doing stuff like this in a regex.

Upvotes: 2

Olivier L.
Olivier L.

Reputation: 2583

You need to group the sections and get rid of the ^ and $.

/(0[1-9]|1[0-2]|[1-9]{1})\/([1-9]{1}|0[1-9]|[1-2]\d|3[0-1])\/((19|20)\d{2})/

Upvotes: 1

Related Questions