views:

73

answers:

2

Hi all,

I'm relativly new to regular expressions but I managed to create a working expression to validate dates (without leap years, and assuming people enter a valid 30 or 31 digit for a month).

This is the expressen: /^\d[1-31]{2}\-\d[1-12]{2}\-\d[1900-2009]{4}$/

But I would like to have a dynamic regular expression like:

$yearSpan = (date("Y") - 110)."-".date("Y");
/^\d[1-31]{2}\-\d[1-12]{2}\-\d[$yearSpan]{4}$/

When I try to use this expression it keeps telling me the compilation failed because a range out of order in character class.

I'm using this expression to validate dates of birth, and it would be nice not to update it every time a year passes by.

Any suggestions?

+2  A: 

You can do it with PHP date and time functions http://php.net/manual/en/function.checkdate.php

Rimian
Thanks for your answer!
Ben Fransen
+3  A: 

I think you should consider using some date/time functions for this purpose.

You're using the character classes in wrong way. [1-31], [1-12] and [1900-2009] will not check for the ranges you have in them. That's not how character classes work and hence that's not how you check for numeric ranges with regex.

A character class [a-r] matches any char from a to r. [a-rx] matches any character from a to r and the character x. Similarly, [1-39] matches any character from 1 to 3 and the character 9 - hence it matches one of 1,2,3 and 9 - and not any number from 1 to 39 as you intended it to.

[1-31]{2} matches two consecutive numbers (the last 1 is redundant), both in the range 1 to 3 - 33 is a valid match.

To match a number from 1 to 31, the correct regex is 0?[1-9]|[1-2][0-9]|3[0-1]. ('0?' takes care of zero padding as in 01-09-2009

For months: 0?[1-9]|1[0-2]

For year: 19[0-9]{2}|200[0-9]

And - is not a meta character outside character classes - you need not escape it.

The correct regex would be:

/^(0?[1-9]|[1-2][0-9]|3[0-1])-(0?[1-9]|1[0-2])-(19[0-9]{2}|200[0-9])$/

If you are not interested in capturing the values, you can write it as:

/^(?:0?[1-9]|[1-2][0-9]|3[0-1])-(?:0?[1-9]|1[0-2])-(?:19[0-9]{2}|200[0-9])$/
Amarghosh
Thanks for you clear answer! I'll use the checkdate function mentioned by Rimian.
Ben Fransen