'Regex for dd-mm-yyyy with leading zeros AND date validation
I'm new to regex and need one to accept (and validate the date) only the dd-mm-yyyy format, with leading zeros for single-digit days or months and only hyphens. I have been able to modify the code given by Ofir Luzon's response here to only allow hyphens but am not able to completely achieve the leading zeros part. Also searched a lot of regex libraries but most solutions either do not validate dates or they allow single digits in the dd and mm parts. Here's the regex:
^(?:(?:31(-)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(-)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(-)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(-)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$
So this accepts dd-mm-yyyy, d-mm-yyyy and dd-m-yyyy, dd-mm-yy, d-m-yy,dd-m-yy, d-mm-yy and validates date, but how to make it restrict to exactly two digits for dd and mm AND four digits for yyyy?
I'm able to understand that the quantifiers for previous tokens need to be changed but am not able to figure out how.
Solution 1:[1]
Here is a suggestion which accepts days from 00-31, months from 00-12 and years from 0000-2999, insisting on 2, 2 and 4 figures.
^([0-2][0-9]|3[01])-(0[0-9]|1[0-2])-[0-2][0-9]{3}$
This does not check for months with less than 31 days. You would do well to use the built-in date functions of whatever language you are working in which will be able to check this.
Modified to include improvements from AmigoJack. 7 characters less in the regex string without changing the matching.
Thank you AmigoJack
Solution 2:[2]
The following pattern will match strings between "01-01-0000" and "31-12-9999"
^(?:0[1-9]|[12][0-9]|3[01])-(?:0[1-9]|1[012])-[0-9]{4}$
However, the string still needs to be validated in the programming language.
Because this pattern doesn't care about how many days there are in a month.
And a pattern that could even account for February, with consideration for the leap years, would be overly complex.
^(?:0[1-9]|1[0-9]|2[0-8])-(?:0[1-9]|1[0-2])-[0-9]{4}$|^(?:(?:31-(?:0[13578]|1[02]))-|(?:(?:29|30)-(?:0[13-9]|1[0-2])-))(?:(?:1[6-9]|[2-9][0-9])[0-9]{2})$|^(?:29-02-(?:(?:(?:1[6-9]|[2-9][0-9])(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
