正则表达式以匹配类型的日期:ddmmyyyy



我正在尝试匹配类型为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$),然后以编程方式检查日期是否有效。

更详细一点:

  1. 匹配^(dd)(dd)(dddd)$(根据需要调整语法)。
  2. 提取三个匹配的组,并以编程方式检查它们是否构成有效日期。

后者需要 (a) 知道每个月有多少天,以及 (b) 知道哪些年份是闰年(这取决于您使用的日历;公历是显而易见的选择,但想想它被引入之前的几年)。

生成的代码将更易于阅读和维护。

(此外,如果您对格式有任何控制,请考虑使用 YYYYMMDD 而不是 DDMMYYYY;它排序正确,并且是 ISO 8601 标准指定的格式之一。

不要仅使用正则表达式来验证日期。您的语言可能有一个内置的日期对象,该对象具有自己的方法,您可以将其与已使用 RegEx 验证其格式的输入结合使用。

最新更新