Archive of June 2012

The Ultimate Date Validation RegExp

Now, I'm not claiming to be a god at regular expressions, but I do own this shirt for a reason. That reason is that I like using RegExp to do a lot of heavy lifting for me. Case in point: validating a date format. It's one thing to pull out year, month and date, allowing for multiple delimiters; it's quite another to ensure that the actual values match expected results. Month values are only between 01 and 12. Days are not only between 01 and 31, but also exclude 29, 30, or 31 if the months aren't supposed to include them — including checking for leap years. I can do that. With Regular Expressions.

Here's how (for simplicty's sake, all years must start with 19xx or 20xx):

var yyyymmdd = /(?:((?:19|20)[0-9]{2})[\/\\\-. ]?(?:(0[1-9]|1[0-2])[\/\\\-. ]?([0-2][1-8]|[12]0|19)|(0[13-9]|1[0-2])[\/\\\-. ]?(29|30)|(0[13578]|1[02])[\/\\\-. ]?(31))|(19(?:[0][48]|[2468][048]|[13579][26])|20(?:[02468][048]|[13579][26]))[\/\\\-. ]?(02)[\/\\\-. ]?(29))/;
//if doing a replace: year is $1$8, month is $2$4$6$9, day is $3$5$7$10
var ddmmyyyy = /(?:(?:([0-2][1-8]|[12]0|19)[\/\\\-. ]?(0[1-9]|1[0-2])|(29|30)[\/\\\-. ]?(0[13-9]|1[0-2])|(31)[\/\\\-. ]?(0[13578]|1[02]))[\/\\\-. ]?((?:19|20)[0-9]{2})|(29)[\/\\\-. ]?(02)[\/\\\-. ]?(19(?:[0][48]|[2468][048]|[13579][26])|20(?:[02468][048]|[13579][26])))/;
//if doing a replace: year is $7$10, month is $2$4$6$9, day is $1$3$5$8
var mmddyyyy = /(?:(?:(0[1-9]|1[0-2])[\/\\\-. ]?([0-2][1-8]|[12]0|19)|(0[13-9]|1[0-2])[\/\\\-. ]?(29|30)|(0[13578]|1[02])[\/\\\-. ]?(31))[\/\\\-. ]?((?:19|20)[0-9]{2})|(02)[\/\\\-. ]?(29)[\/\\\-. ]?(19(?:[0][48]|[2468][048]|[13579][26])|20(?:[02468][048]|[13579][26])))/;
//if doing a replace: year is $7$10, month is $1$3$5$8, day is $2$4$6$9

I'll break down the first example.
The entire expression looks for most likely values first, then looks for less likely, yet still valid values.

  • First it looks for a year with
    • a month value is between 01-12 and the day value is between 01-28.
    • If not, it checks if the month value is 01, or 03-12 and the day is either 29 or 30.
    • Failing that, it checks if the month is one of 01,03,05,07,08,10, or 12 and the day is 31.
  • Failing that, it does one last sanity check to see if the year was a leap year (only checking the years starting with 19xx or 20xx, so values are actually easily calculatable) and the date is 02-29.

If all of that fails, it isn't a valid date.

Tags: , , , ,
2012.06.07 10:23 AM | Permalink 0 Comments