我需要用正则表达式验证格式为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格式?
当前回答
import re
expression = "Nov 05 20:10:09 2020"
reg_ex = r'((Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([0-2][0-9]|(3)[0-1]) (([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])) (\d{4}))'
assert re.fullmatch(reg_ex, expression), True
对给定例子的解释
11月=一组可能的月份,即(Jan|Feb|Mar|Apr|五月|六月|七月|八月|九月|十月|十一月|十二月) 05年=天即一组有效。([0 - 9][0]| (3)(0 - 1)) 20:10:09 =获得有效时间:一组([0 - 9][0 - 1]| 2(0 - 3)),分钟:([0 - 9][0 - 5])和秒:([0 - 9][0 - 5]) 2020 =获取年份的一组,即(\d{4}))
其他回答
试试这个。
^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$
您可以在http://www.regular-expressions.info/javascriptexample.html轻松地测试正则表达式。
^(((([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)
我怀疑,在不知道用户的地区何时从儒略历切换到格里高利历的情况下,以下内容是尽可能准确的。
它接受'-','/',或者什么都不作为年,月和日之间的分隔符,不管顺序如何。
MMddyyyy:
^(((0[13-9]|1[012])[-/]?(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])[-/]?31|02[-/]?(0[1-9]|1[0-9]|2[0-8]))[-/]?[0-9]{4}|02[-/]?29[-/]?([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00))$
ddMMyyyy:
^(((0[1-9]|[12][0-9]|30)[-/]?(0[13-9]|1[012])|31[-/]?(0[13578]|1[02])|(0[1-9]|1[0-9]|2[0-8])[-/]?02)[-/]?[0-9]{4}|29[-/]?02[-/]?([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00))$
yyyyMMdd:
^([0-9]{4}[-/]?((0[13-9]|1[012])[-/]?(0[1-9]|[12][0-9]|30)|(0[13578]|1[02])[-/]?31|02[-/]?(0[1-9]|1[0-9]|2[0-8]))|([0-9]{2}(([2468][048]|[02468][48])|[13579][26])|([13579][26]|[02468][048]|0[0-9]|1[0-6])00)[-/]?02[-/]?29)$
除了顺序,这些都精确到儒略历(每四年闰年),直到1700年,当公历与儒略历背离。它有两个问题:
It accepts the year 0000, which doesn't exist in many, but not all, standards. Note that ISO 8601 does accept year 0000 (equivalent to 1 BCE). It doesn't skip the 10-13 days which were lost when the Gregorian Calendar came into use. This varies by locality though. For example, the Roman Catholic Church skipped 10 days, October 5th through October 14th, 1582, but Greece (the last to switch) skipped February 16th through the 28th of 1923, 13 days, having to take into account the leap years of 1700, 1800, and 1900.
从0001年到9999年的Java日历实现已经测试了这一点,唯一的差异是上面提到的1582年的10天。
进一步扩展了@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,他们为我们所有人创造了如此优秀的正则表达式!
我认为最好的方法是使用Moment.js的isValid()方法,指定格式并使用严格的解析。
正如moment.js文档所说
从2.3.0版本开始,您可以为最后一个参数指定一个布尔值 使Moment使用严格解析。严格解析要求 格式和输入完全匹配,包括分隔符。
value = '2020-05-25';
format = 'YYYY-MM-DD';
moment(value, format, true).isValid() // true