Comment: Leap Years are any year that can be evenly divided by 4
Comment: (such as 2012, 2016, etc)
Comment: • except if it can be evenly divided by 100
Comment: then it isn't (such as 2100, 2200, etc)
Comment: • except if it can be evenly divided by 400,
Comment: then it is (such as 2000, 2400)
Comment: https://www.mathsisfun.com/leap-years.html
Comment: -------------------------------------------------
Comment: verify date dd/mm/yyyy; possible separators: -.,/
Comment: valid year range: 0000-9999
^start of line
Comment: start anchor
Comment: precheck xx-xx-xxxx,... add new separators here
Positive Lookahead(?=\d{2}([-.,\/])\d{2}\1\d{4}$) \d{2}a digit, repeated exactly 2 times
-the literal - (4510 / 558 / 2D16)
.the literal . (4610 / 568 / 2E16)
,the literal , (4410 / 548 / 2C16)
\/the literal / (4710 / 578 / 2F16)
\d{2}a digit, repeated exactly 2 times
\1the text saved by group 1
\d{4}a digit, repeated exactly 4 times
$end of line
Non-Capturing Group(?: # day-check: non caturing group
# days 01-28
0[1-9]|1\d|[2][0-8]|
# february 29d check for leap year: all 4y / 00 years: only each 400
# 0400,0800,1200,1600,2000,...
29
(?!.02. # not if feb: if not ...
(?!
# 00 years: exclude !0 %400 years
(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)
# 00,04,08,12,...
\d{2}(?:[02468][048]|[13579][26])
)
)|
# d30 negative lookahead: february cannot have 30 days
30(?!.02)|
# d31 positive lookahead: month up to 31 days
31(?=.(?:0[13578]|10|12))
) 1st Alternative # day-check: non caturing group
# days 01-28
0[1-9] Comment: day-check: non caturing group
Comment: days 01-28
0the literal text 0
1-9one character from 1 (4910) to 9 (5710)
1the literal 1 (4910 / 618 / 3116)
\da digit
2the literal 2 (5010 / 628 / 3216)
0-8one character from 0 (4810) to 8 (5610)
4th Alternative
# february 29d check for leap year: all 4y / 00 years: only each 400
# 0400,0800,1200,1600,2000,...
29
(?!.02. # not if feb: if not ...
(?!
# 00 years: exclude !0 %400 years
(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)
# 00,04,08,12,...
\d{2}(?:[02468][048]|[13579][26])
)
) Comment: february 29d check for leap year: all 4y / 00 years: only each 400
Comment: 0400,0800,1200,1600,2000,...
Negative Lookahead(?!.02. # not if feb: if not ...
(?!
# 00 years: exclude !0 %400 years
(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)
# 00,04,08,12,...
\d{2}(?:[02468][048]|[13579][26])
)
) .any character (except for line terminators)
.any character (except for line terminators)
Comment: not if feb: if not ...
Negative Lookahead(?!
# 00 years: exclude !0 %400 years
(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)
# 00,04,08,12,...
\d{2}(?:[02468][048]|[13579][26])
) Comment: 00 years: exclude !0 %400 years
Negative Lookahead(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00) Non-Capturing Group(?:[02468][1-35-79]|[13579][0-13-57-9]) 1st Alternative[02468][1-35-79] 0the literal 0 (4810 / 608 / 3016)
2the literal 2 (5010 / 628 / 3216)
4the literal 4 (5210 / 648 / 3416)
6the literal 6 (5410 / 668 / 3616)
8the literal 8 (5610 / 708 / 3816)
1-3one character from 1 (4910) to 3 (5110)
5-7one character from 5 (5310) to 7 (5510)
9the literal 9 (5710 / 718 / 3916)
2nd Alternative[13579][0-13-57-9] 1the literal 1 (4910 / 618 / 3116)
3the literal 3 (5110 / 638 / 3316)
5the literal 5 (5310 / 658 / 3516)
7the literal 7 (5510 / 678 / 3716)
9the literal 9 (5710 / 718 / 3916)
Character Class[0-13-57-9] 0-1one character from 0 (4810) to 1 (4910)
3-5one character from 3 (5110) to 5 (5310)
7-9one character from 7 (5510) to 9 (5710)
Comment: 00,04,08,12,...
\d{2}a digit, repeated exactly 2 times
Non-Capturing Group(?:[02468][048]|[13579][26]) 1st Alternative[02468][048] 0the literal 0 (4810 / 608 / 3016)
2the literal 2 (5010 / 628 / 3216)
4the literal 4 (5210 / 648 / 3416)
6the literal 6 (5410 / 668 / 3616)
8the literal 8 (5610 / 708 / 3816)
0the literal 0 (4810 / 608 / 3016)
4the literal 4 (5210 / 648 / 3416)
8the literal 8 (5610 / 708 / 3816)
2nd Alternative[13579][26] 5th Alternative
# d30 negative lookahead: february cannot have 30 days
30(?!.02) 6th Alternative
# d31 positive lookahead: month up to 31 days
31(?=.(?:0[13578]|10|12))
Comment: eof day-check
Comment: month 01-12
.any character (except for line terminators)
Non-Capturing Group(?:0[1-9]|1[012]) Comment: year 0000-9999
.any character (except for line terminators)
\d{4}a digit, repeated exactly 4 times
$end of line
Comment: end anchor
g modifier: global. Finds all matches instead of stopping after the first
m modifier: multiline. Causes ^ and $ to match the start and end of each line, not only the start and end of the string
x modifier: extended. Ignores unescaped whitespace and comments outside character classes