我需要用正则表达式验证格式为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格式?


当前回答

我正在使用一个只接受MM/DD/YYYY格式的API。我找不到任何一篇文章能像Ofir的回答一样解释闰年,所以我对它进行了调整,并在这里重新发布给任何可能需要它的人。

/^(?:(?:(?:0[13578]|1[02])(\/)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/

其他回答

我认为最好的方法是使用Moment.js的isValid()方法,指定格式并使用严格的解析。

正如moment.js文档所说

从2.3.0版本开始,您可以为最后一个参数指定一个布尔值 使Moment使用严格解析。严格解析要求 格式和输入完全匹配,包括分隔符。

value = '2020-05-25';
format = 'YYYY-MM-DD';
moment(value, format, true).isValid() // true

这是一个正则表达式,用于匹配日期格式的字符串,YYYY-MM-DD,使用不同类型的分隔符。它甚至在句子中匹配字符串,并且日期以st, nd和其他结尾。

举个例子,它与下面句子中的日期相匹配:

"Her birthday is 2022 February 23rd; I will present here a gift."

"Her birthday is 2022 Feb 23rd; I will present here a gift."

"Her birthday is 2022 02 23; I will present here a gift."

这是日期正则表达式:

"\b
(?<YYYY>[0-9]{4})
(?<!0000)(?<sep>[ /.,-])
(?|
    (?:(?<MM>0[13578]|1[02]|Jan(?:uary)?|Mar(?:ch)?|May|Jul(?:y)?|Aug(?:ust)?|Oct(?:ober)?|Dec(?:ember)?)\g{sep}(?<DD>0[1-9]|[12][0-9]|3[01]))|
    (?:(?<MM>0[469]|11|Apr(?:il)?|Jun(?:e)?|Sep(?:tember)?|Nov(?:ember)?)\g{sep}(?<DD>0[1-9]|[12][0-9]|30))|
    (?:(?<MM>02|Feb(?:ruary)?)\g{sep}(?<DD>0[1-9]|[12][0-9]))
)
(?:
    (?<=[023][1])st|
    (?<=[02][2])nd|
    (?<=[02][3])rd|
    (?<=(?:0[4-9])|(?:1[0-9])|20|(?:2[4-9])|30)th
)?
[,;.]?
\b"x

以我之见,对于正则表达式来说,检查闰年是没有意义的,因为可以为它编写简单、清晰和可理解的一行代码:

is_leap_year(y) = ((y%4 == 0) && (y%100 != 0)) || (y%400 == 0)

正则表达式是用来匹配字符串的,而不是用来进行计算的。最好的方法是匹配字符串,然后将捕获的MM组传递给is_leap_year函数(如果是02、Feb或February),以验证字符串。

你粘贴的正则表达式没有正确地验证闰年,但在同一篇文章中有一个正则表达式。 我将其修改为dd/mm/yyyy, dd-mm-yyyy或dd.mm.yyyy。

^(?:(?: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})$

我在Arun提供的答案和这里的链接中测试了一下,它似乎有效。

编辑2019年2月14日:我已经删除了正则表达式中允许29-0,-11等日期的逗号

python的简单函数

def is_valid_date(date_text):
    pattern = re.compile('\d{4}-\d{2}-\d{2}$')
    return pattern.match(date_text)

另一种答案,根据月(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]))))$