我正在尝试匹配类型为ddmmyyyy
的日期 ,如:04072001
到目前为止,我有这个:
^(?:(?:31(?:0?[13578]|1[02]))1|(?:(?:29|30)(?:0?[1,3-9]|1[0-2])2))(?:(?:1[6-9]|[2-9]d)?d{2})$|^(?:290?23(?:(?:(?:1[6-9]|[2-9]d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1d|2[0-8])(?:(?:0?[1-9])|(?:1[0-2]))4(?:(?:1[6-9]|[2-9]d)?d{2})$
这几乎与这里相同,但没有分隔符((/|-|.)
)
你可以使用更简单的东西,比如这样:
^(0[1-9]|[1-2][0-9]|31(?!(?:0[2469]|11))|30(?!02))(0[1-9]|1[0-2])([12]d{3})$
它捕获日、月、年,并验证除 2 月 29 日是否实际上是闰年之外的所有内容。(为此,我只需在之后对捕获的年份/日期执行数学运算,而不是尝试将其写入表达式)。
工作示例:http://regex101.com/r/dH8mG3
解释:
- Capture the day: 01-29
- OR 31, if not succeeded by 02, 04, 06, 09, or 11
- OR 30, if not succeeded by 02
- Capture the month: 01-12
- Capture the year: 1000-2999 (you could narrow this down
by using number ranges like
(1[8-9]d{2}|20d{2}) == 1800-2099
正则表达式不是完成这项工作的最佳工具。
如果可能的话,只需匹配^d{8}$
(如果您的正则表达式引擎不支持{8}
语法,则匹配^dddddddd$
),然后以编程方式检查日期是否有效。
更详细一点:
- 匹配
^(dd)(dd)(dddd)$
(根据需要调整语法)。 - 提取三个匹配的组,并以编程方式检查它们是否构成有效日期。
后者需要 (a) 知道每个月有多少天,以及 (b) 知道哪些年份是闰年(这取决于您使用的日历;公历是显而易见的选择,但想想它被引入之前的几年)。
生成的代码将更易于阅读和维护。
(此外,如果您对格式有任何控制,请考虑使用 YYYYMMDD 而不是 DDMMYYYY;它排序正确,并且是 ISO 8601 标准指定的格式之一。
不要仅使用正则表达式来验证日期。您的语言可能有一个内置的日期对象,该对象具有自己的方法,您可以将其与已使用 RegEx 验证其格式的输入结合使用。