我需要使用常规表达式验证格式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
格式的有效正则表达式是什么?
答案 0 :(得分:269)
您粘贴的正则表达式不能正确验证闰年,但有一个in the same post。
我将其修改为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链接中测试了一下,here它似乎也有效。
编辑2019年2月14日:我删除了正则表达式中的逗号,该逗号允许29-0,-11
等日期
答案 1 :(得分:225)
根据我的要求,我已将@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})$
并在此处测试了一些测试用例http://regexr.com/39tr1。
为了更好地理解此正则表达式,请参阅此图像:
答案 2 :(得分:61)
注意:
你的正则表达式在“4倍和100倍,但不是400倍”的倍数下不起作用。通过该测试的年数不是闰年。例如:1900,2100,2200,2300,2500等。换句话说,它将格式\ d \ d00的所有年份放在同一类闰年中,这是不正确的。 - MuchToLearn
所以它只适用于[1901 - 2099](Whew)
DD / MM / YYYY:
检查闰年。 从1900年到9999年是有效的。只有dd / MM / yyyy
(^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|((29|30|31)[\/](0[13578]|1[02]))|((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|(^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)
答案 3 :(得分:13)
试试这个。
^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$
您可以轻松地在http://www.regular-expressions.info/javascriptexample.html测试正则表达式。
答案 4 :(得分:10)
对于那些看过这些并完全混淆的人,这里是我脚本的摘录。不幸的是,它所做的只是在日期时间输入中匹配有效数字,并且2月31日将被标记为有效,但正如许多人所说,正则表达式确实不是进行此测试的最佳工具。
要匹配格式为'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
不会
答案 5 :(得分:9)
这是另一个正则表达式版本,可以匹配以下任何日期格式,并允许省略前导零:
正则表达式: ^[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2}$
<强>匹配强>
1/1/11 or 1.1.11 or 1-1-11 : true
01/01/11 or 01.01.11 or 01-01-11 : true
01/01/2011 or 01.01.2011 or 01-01-2011 : true
01/1/2011 or 01.1.2011 or 01-1-2011 : true
1/11/2011 or 1.11.2011 or 1-11-2011 : true
1/11/11 or 1.11.11 or 1-11-11 : true
11/1/11 or 11.1.11 or 11-1-11 : true
答案 6 :(得分:8)
我怀疑在不知道用户的区域设置何时从Julian切换到Gregorian日历时,以下内容与预期的一样准确。
它接受&#39; - &#39;,&#39; /&#39;,或者在年,月,日之间不作为分隔符,无论顺序如何。
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年,当格里高利历从朱利安分歧。它有两个问题:
这已经针对Java的日历实施从0001年到9999年进行了测试,唯一的差异是1582年的上述10天。
答案 7 :(得分:5)
发现此reg here
^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$
这会正确验证格式mm/dd/yyyy
和有效日期(但不是m/d/yyyy
)。
答案 8 :(得分:4)
我在这里为dd/mm/yyyy
写了一个,其中分隔符可以是-.,/
年范围0000-9999
之一。
它处理leap years,专为正则表达式风格,that support前瞻,捕获组和反向引用而设计。不适用于d/m/yyyy
等。如果需要,请将其他分隔符添加到[-.,/]
^(?=\d{2}([-.,\/])\d{2}\1\d{4}$)(?:0[1-9]|1\d|[2][0-8]|29(?!.02.(?!(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)\d{2}(?:[02468][048]|[13579][26])))|30(?!.02)|31(?=.(?:0[13578]|10|12))).(?:0[1-9]|1[012]).\d{4}$
Test at regex101;作为Java字符串:
"^(?=\\d{2}([-.,\\/])\\d{2}\\1\\d{4}$)(?:0[1-9]|1\\d|[2][0-8]|29(?!.02.(?!(?!(?:[02468][1-35-79]|[13579][0-13-57-9])00)\\d{2}(?:[02468][048]|[13579][26])))|30(?!.02)|31(?=.(?:0[13578]|10|12))).(?:0[1-9]|1[012]).\\d{4}$"
说明:
(?x) # modifier x: free spacing mode (for comments)
# verify date dd/mm/yyyy; possible separators: -.,/
# valid year range: 0000-9999
^ # start anchor
# precheck xx-xx-xxxx,... add new separators here
(?=\d{2}([-.,\/])\d{2}\1\d{4}$)
(?: # 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))
) # eof day-check
# month 01-12
.(?:0[1-9]|1[012])
# year 0000-9999
.\d{4}
$ # end anchor
另见SO Regex FAQ;如果失败,请告诉我。
答案 9 :(得分:4)
以下表达式很好且易于操作:
((((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]))
希望这对你有很大的帮助
答案 10 :(得分:4)
"^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((19|20)\\d\\d)$"
将验证1900-2099
答案 11 :(得分:3)
根据月份(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]))))$
答案 12 :(得分:1)
我正在使用仅接受MM / DD / YYYY格式的API。我找不到任何其他闰年的帖子和Ofir's answer一样,所以我调整了它并在这里重新发布给任何可能需要它的人。
/^(?:(?:(?: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})$/
答案 13 :(得分:1)
对我来说,最好的方法是通过指定格式并使用严格的语法来使用Moment.js isValid()方法。
正如moment.js文档所述
从2.3.0版开始,您可以为最后一个参数指定布尔值 使Moment使用严格的解析。严格解析要求 格式和输入完全匹配,包括定界符。
value = '2020-05-25';
format = 'YYYY-MM-DD';
moment(value, format, true).isValid() // true
答案 14 :(得分:1)
1. dd mmm YYYY
(除了 dd-mmm-YYYY
、dd/mmm/YYYY
、dd.mmm.YYYY
)。
2. mmm 为所有大写字母格式(除了标题格式)
dd mmm YYYY
例如30 Apr 2026
或 24 DEC 2028
很受欢迎。
扩展正则表达式:
(^(?:(?:(?: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 Demo 中包含的测试用例
功能(保留):
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)< /li>
一些额外的小修饰如下:
包含 Ofir Luzon 于 2019 年 2 月 14 日的修复,以删除正则表达式中的逗号,该逗号允许日期为 29-0,-11 [错误复制到 Alok Chaudhary 的正则表达式]
将 (\/|-|\.)
替换为 ([-.\/])
以尽量减少反斜杠的使用。 \/
仍然用于支持一些正则表达式风格,例如PCRE(PHP) 虽然有一些其他的正则表达式风格,例如Python 可以简单地在字符类 [ ]
/
在整个正则表达式周围添加了一对括号 () 以使其成为整个匹配字符串的捕获组。这对于使用 findAll 类型的函数来获取匹配项列表的人很有用(例如 Python 中的 re.findall
)。这使我们能够使用以下代码捕获多行字符串中的所有匹配字符串:
re.findall
示例代码:
match_list = re.findall(regex, source_string)
for item in match_list:
print(item[0])
感谢 Ofir Luzon 和 Alok Chaudhary,他们为我们所有人创造了如此出色的正则表达式!
答案 15 :(得分:0)
((((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-9][0-9])))|((02)\/(29)\/(19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))
将使用MM/DD/YYYY
至1960
2028
格式
如果您需要延长闰年支持,请添加
19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048]|3[26]|4[048])))
这也是工作
^((((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-9][0-9])))|((02)[/](29)[/](19(6[048]|7[26]|8[048]|9[26])|20(0[048]|1[26]|2[048])))
如果您可以更改格式mm-dd-yyyy
而不是将[/]
替换为[-]
还可以在线查看http://regexr.com/
答案 16 :(得分:0)
对于日期MM / DD / YYYY,您可以使用
^((((0[13578])|([13578])|(1[02]))[\/](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/](([1-9])|([0-2][0-9])|(30)))|((2|02)[\/](([1-9])|([0-2][0-9]))))[\/]\d{4}$|^\d{4}$
验证适当的日子和飞蛾。
请记住,您可以在
查看正则表达式我建议:)
玩得开心!
答案 17 :(得分:0)
obj.test = {};
obj.test.test = "test";
此正则表达式将以格式验证日期:
12-30-2016(mm-dd-yyyy)或12-3-2016(mm-d-yyyy)或 1-3-2016(m-d-yyyy)或1-30-2016(m-dd-yyyy)
答案 18 :(得分:0)
我知道这是该问题的切向答案,但是如果问题的意图是“如何验证日期?”,那么为什么不尝试让编程语言来完成所有任务呢?努力工作(如果您使用的是可以使用的语言)?
例如在php
$this_date_object = date_create($this_date);
if ($this_date_object == false )
{
// process the error
}
答案 19 :(得分:0)
仅在当天使用:
<input placeholder="day" maxlength="2" minlength="1" formControlName="birthDay"
name="birthDay"pattern="(0[1-9]|1[0-9]|2[0-9]|3[0-1])" >/
仅用于月份:
<input placeholder="month" maxlength="2" minlength="1"
formControlName="month" name="month" formControlName="month" name="month" pattern="(0[1-
9]|1[0-2])">/
答案 20 :(得分:0)
如果您要查找特定格式,则仅基于Alok答案,这对“ dd / MM / yyyy”和“ dd / MMM / yyyy”日期格式有效。
function isValidDateFormatDDMMYYYY(inputDate) {
var date_regex = /^(?:(?: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})$/;
return date_regex.test(inputDate);
}
通过该代码工作的示例很少-
谢谢
答案 21 :(得分:0)
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
关于给定示例的说明
A group of possible months i.e. (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
A group of valid days i.e. ([0-2][0-9]|(3)[0-1])
A group for getting valid Hours : ([0-1][0-9]|2[0-3]), Minutes : ([0-5][0-9]) and Seconds : ([0-5][0-9])
A group for getting year i.e (\d{4}))
答案 22 :(得分:0)
请跟随表情
Regex regex = new Regex(@"(((0|1)[0-9]|2[0-9]|3[0-1])\/(0[1-9]|1[0-2])\/((19|20)\d\d))$");