我需要用正则表达式验证格式为dd/mm/yyyy的日期字符串。
这个正则表达式验证dd/mm/yyyy,但不验证像31/02/4500这样的无效日期:
^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$
什么是有效的正则表达式来验证支持闰年的dd/mm/yyyy格式?
我需要用正则表达式验证格式为dd/mm/yyyy的日期字符串。
这个正则表达式验证dd/mm/yyyy,但不验证像31/02/4500这样的无效日期:
^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$
什么是有效的正则表达式来验证支持闰年的dd/mm/yyyy格式?
当前回答
进一步扩展了@AlokChaudhary给出的正则表达式,以支持:
1. dd mmm YYYY(除了dd-mmm-YYYY, dd/mmm/YYYY, dd.mmm.YYYY)。
2. 所有大写字母格式的mmm(除了标题格式)
dd mmm YYYY,例如2026年4月30日或2028年12月24日是流行的。
扩展正则表达式:
(^(?:(?:(?:31(?:(?:([-.\/])(?:0?[13578]|1[02])\1)|(?:([-.\/ ])(?:Jan|JAN|Mar|MAR|May|MAY|Jul|JUL|Aug|AUG|Oct|OCT|Dec|DEC)\2)))|(?:(?:29|30)(?:(?:([-.\/])(?:0?[13-9]|1[0-2])\3)|(?:([-.\/ ])(?:Jan|JAN|Mar|MAR|Apr|APR|May|MAY|Jun|JUN|Jul|JUL|Aug|AUG|Sep|SEP|Oct|OCT|Nov|NOV|Dec|DEC)\4))))(?:(?:1[6-9]|[2-9]\d)?\d{2}))$|^(?:29(?:(?:([-.\/])(?:0?2)\5)|(?:([-.\/ ])(?:Feb|FEB)\6))(?:(?: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])))\7)|(?:([-.\/ ])(?:Jan|JAN|Feb|FEB|Mar|MAR|May|MAY|Jul|JUL|Aug|AUG|Oct|OCT|Dec|DEC)\8))(?:(?:1[6-9]|[2-9]\d)?\d{2}))$)
Regex演示中包含的测试用例
特性(保留):
闰年检查(2月29日验证)包括以下逻辑:(能被4整除但不能被100整除)或(能被400整除) 支持1600 ~ 9999年 支持dd/mm/YYYY、dd-mm-YYYY、dd.mm.YYYY(不支持dd mm YYYY) 支持dd mmm YYYY、dd-mmm-YYYY、dd/mmm/YYYY、dd.mmm.YYYY(新增dd mmm YYYY)。mmm可以是大写的,如DEC或标题格式,如DEC)
一些额外的小润色如下:
Included the fix by Ofir Luzon on February 14th 2019 to remove a comma that was in the regex which allowed dates like 29-0,-11 [error replicated to Alok Chaudhary's regex] Replaced (\/|-|\.) by ([-.\/]) to minimize the use of backslash. \/ is still used in order to support some regex flavor e.g. PCRE(PHP) although some other regex flavor e.g. Python can simply use / inside the character class [ ] Added a pair of parenthesis () surrounding the whole regex to make it a capturing group for the whole matching string. This is useful for people using findAll type of functions to get a matching item list (e.g. re.findall in Python). This enable us to capture all the matching strings within a mult-line string with the following codes:
Re.findall示例代码:
match_list = re.findall(regex, source_string)
for item in match_list:
print(item[0])
扩展正则表达式图像:
应该归功于Ofir Luzon和Alok Chaudhary,他们为我们所有人创造了如此优秀的正则表达式!
其他回答
下面的表达式很好,也很容易操作:
((((0[13578]|1[02])(\/|-|.)(0[1-9]|1[0-9]|2[0-9]|3[01]))|((0[469]|11)(\/|-|.)(0[1-9]|1[0-9]|2[0-9]|3[0]))|((02)((\/|-|.)(0[1-9]|1[0-9]|2[0-8]))))(\/|-|.)(19([6-9][0-9])|20(0[0-9]|1[0-4])))|((02)(\/|-|.)(29)(\/|-|.)(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26])))
它根据MM/dd/YYYY格式进行验证,并允许从1960年到2016年的闰年支持。如果你需要扩展闰年支持,你只需要操作表达式的这一部分:
(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]))
希望这对你有帮助
另一种答案,根据月(mm)和年(yyyy)验证日(dd)(即,在闰年也验证2月29日),并允许年范围从0001到9999(根据公历,0000是无效年)
^(?:(?:(?:0[1-9]|[12]\d|3[01])/(?:0[13578]|1[02])|(?:0[1-9]|[12]\d|30)/(?:0[469]|11)|(?:0[1-9]|1\d|2[0-8])/02)/(?!0000)\d{4}|(?:(?:0[1-9]|[12]\d)/02/(?:(?!0000)(?:[02468][048]|[13579][26])00|(?!..00)\d{2}(?:[02468][048]|[13579][26]))))$
下面是regex的另一个版本,它可以匹配以下任何日期格式,并允许省略前导零:
Regex: ^(0 - 3) ?[0 - 9][0 - 3] ?[0 - 9]。(?:[0 - 9]{2})?[0 - 9] {2} $
匹配:
1/1/11或1.1.11或1-1-11:true 01/01/11或01.01.11或01-01-11:true 01/01/2011或011.01.2011或01-01-2011:true 01/1/2011或01.1.2011或01-1-2011:true 1/11/2011或1.11.2011或1-11-2011:true 1/11/11或1.11.11或1-11-11:true 11/1/11或11.1.11或11-1-11:true
Debuggex演示
^(((([13578]|0[13578]|1[02])[-](0[1-9]|[1-9]|1[0-9]|2[0-9]|3[01]))|(([469]|0[469]|11)[-]([1-9]|1[0-9]|2[0-9]|3[0]))|((2|02)([-](0[1-9]|1[0-9]|2[0-8]))))[-](19([6-9][0-9])|20([0-9][0-9])))|((02)[-](29)[-](19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))
这个正则表达式将验证日期的格式:
12-30-2016 (mm-dd-yyyy)或12-3-2016 (mm-d-yyyy)或 1-3-2016 (m-d-yyyy)或1-30-2016 (m-dd-yyyy)
我已经根据我的要求扩展了@Ofir Luzon给出的格式dd-mmm-YYYY, dd/mmm/YYYY, dd.mmm.YYYY。任何有同样要求的人都可以参考这个
^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)(?:0?2|(?:Feb))\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]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$
并在这里测试了一些测试用例https://regexr.com/39tr1。
为了更好地理解这个正则表达式,请参考下面的图片:
Edit
将其扩展为yyyy/mm/dd、yyyy-mm-dd或yyyy.mm.dd 一些测试用例https://regex101.com/r/3TZfyU/1
^(?:(?:1[6-9]|[2-9]\d)?\d{2})(?:(?:(\/|-|\.)(?:0?[13578]|1[02])\1(?:31))|(?:(\/|-|\.)(?:0?[13-9]|1[0-2])\2(?:29|30)))$|
^(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\/|-|\.)0?2\3(?:29)$|
^(?:(?:1[6-9]|[2-9]\d)?\d{2})(\/|-|\.)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:0?[1-9]|1\d|2[0-8])$