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

其他回答

下面的表达式很好,也很容易操作:

((((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]))

希望这对你有帮助

对于那些看到这些并感到完全困惑的人,这里是我剧本的一段摘录。不幸的是,它所做的只是匹配日期时间输入中的有效数字,31 Feb将被标记为有效,但正如许多人所说,regex真的不是做这个测试的最佳工具。

以'yyyy-MM-dd hh:mm'格式匹配日期(实际上可以按您喜欢的任何顺序匹配)

var dateerrors = false;
var yearReg = '(201[4-9]|202[0-9])';            ///< Allows a number between 2014 and 2029
var monthReg = '(0[1-9]|1[0-2])';               ///< Allows a number between 00 and 12
var dayReg = '(0[1-9]|1[0-9]|2[0-9]|3[0-1])';   ///< Allows a number between 00 and 31
var hourReg = '([0-1][0-9]|2[0-3])';            ///< Allows a number between 00 and 24
var minReg = '([0-5][0-9])';                    ///< Allows a number between 00 and 59
var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');
$('input').filter(function () {return this.id.match(/myhtml_element_with_id_\d+_datetime/);}).each(function (e) {
    if (e > 0) {
        // Don't test the first input. This will use the default
        var val = $(this).val();
        if (val && !val.trim().match(reg)) {
            dateerrors = true;
            return false;
        }
    }
});
if (dateerrors) {
    alert('You must enter a validate date in the format "yyyy-mm-dd HH:MM", e.g. 2019-12-31 19:30');
    return false;
}

上面的脚本首先构建一个正则表达式对象。然后它会找到id与某个模式匹配的所有输入,然后循环遍历这些输入。我没有测试我找到的第一个输入(if (e > 0))。

稍微解释一下:

var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');

^表示匹配的开始,而$表示匹配的结束。

return this.id.match(/myhtml_element_with_id_\d+_datetime/);

\d+表示匹配单个或连续的整数序列,因此myhtml_element_with_id_56_datetime和myhtml_element_with_id_2_datetime将匹配,但myhtml_element_with_id_5a_datetime将不匹配

year  = ((20[012]\d|19\d\d)|(1\d|2[0123])) 
month = ((0[0-9])|(1[012]))
day   = ((0[1-9])|([12][0-9])|(3[01]))

year-month-day = (((20[012]\d|19\d\d)|(1\d|2[0123]))-((0[0-9])|(1[012]))-((0[1-9])|([12][0-9])|(3[01])))
day-month-year = (((0[1-9])|([12][0-9])|(3[01]))-((0[0-9])|(1[012]))-((20[012]\d|19\d\d)|(1\d|2[0123])))
year/month/day = (((20[012]\d|19\d\d)|(1\d|2[0123]))\/((0[0-9])|(1[012]))\/((0[1-9])|([12][0-9])|(3[01])))
month/day/year = (((0[0-9])|(1[012]))\/((0[1-9])|([12][0-9])|(3[01]))\/((20[012]\d|19\d\d)|(1\d|2[0123])))
day/month/year = (((0[1-9])|([12][0-9])|(3[01]))\/((0[0-9])|(1[012]))\/((20[012]\d|19\d\d)|(1\d|2[0123])))
day.month.year = (((0[1-9])|([12][0-9])|(3[01]))\.((0[0-9])|(1[012]))\.((20[012]\d|19\d\d)|(1\d|2[0123])))
year.month.day = (((20[012]\d|19\d\d)|(1\d|2[0123]))\.((0[0-9])|(1[012]))\.((0[1-9])|([12][0-9])|(3[01])))


all = (((20[012]\d|19\d\d)|(1\d|2[0123]))-((0[0-9])|(1[012]))-((0[1-9])|([12][0-9])|(3[01])))|(((0[1-9])|([12][0-9])|(3[01]))-((0[0-9])|(1[012]))-((20[012]\d|19\d\d)|(1\d|2[0123])))|(((20[012]\d|19\d\d)|(1\d|2[0123]))\/((0[0-9])|(1[012]))\/((0[1-9])|([12][0-9])|(3[01])))|(((0[0-9])|(1[012]))\/((0[1-9])|([12][0-9])|(3[01]))\/((20[012]\d|19\d\d)|(1\d|2[0123])))|(((0[1-9])|([12][0-9])|(3[01]))\/((0[0-9])|(1[012]))\/((20[012]\d|19\d\d)|(1\d|2[0123])))|(((0[1-9])|([12][0-9])|(3[01]))\.((0[0-9])|(1[012]))\.((20[012]\d|19\d\d)|(1\d|2[0123])))|(((20[012]\d|19\d\d)|(1\d|2[0123]))\.((0[0-9])|(1[012]))\.((0[1-9])|([12][0-9])|(3[01])))

它的工作是

yyyy-mm-dd
dd-mm-yyyy
yyyy/mm/dd
mm/dd/yyyy
dd/mm/yyyy
dd.mm.yyyy
yyyy.mm.dd

yy-mm-dd
dd-mm-yy
yyyy/mm/dd
mm/dd/yy
dd/mm/yy
dd.mm.yy
yy.mm.dd

但不适用于日= d或月= m,例如d.m.y 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}))

你粘贴的正则表达式没有正确地验证闰年,但在同一篇文章中有一个正则表达式。 我将其修改为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等日期的逗号