cakephp 的日期正则表达式匹配错误的日期

cakephp's date regular expression matches wrong date

我正在查看 cake 的库并在其 Validation.php 文件中找到了日期的正则表达式。我将它用于各种日期值,发现它甚至可以匹配某些特定日期的错误日期值。

例如,它与以下日期完美匹配(实际上,它应该):-

20/01/2011
19/09/2017
20/01/1601

但是当我使用错误的日期值 29 and/or 30 作为日期时,令人惊讶的是它也匹配它们(它不应该):-

30/,/1601
29/,/2017

https://regex101.com/r/8Q96bd/1/

一件更有趣的事情是,如果你改变日期并使用除 30 和 29 之外的另一个日期,那么表达式将不会匹配它。

使用除 29 和 30 以外的任何其他日期,但不匹配:-

28/,/1600

https://regex101.com/r/UKuPWU/1/

那么,如果 cakephp 的日期正则表达式包含 30 和 29 作为日期,那么到底为什么会匹配错误的日期值?

表达式如下:-

^(?:(?:(?:31(\\/|-|\.|\x20))(?:0?[13578]|1[02]))|(?:(?:29|30)([-\/])(?:0?[1,3-9]|1[0-2])))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29([-\/])0?2(?:(?:(?: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]))(?:(?:1[6-9]|[2-9]\d)?\d{2})$

你可以在 cakephp lib 目录中找到这个表达式(不过我使用的是 cake 2.x)。

\lib\Cake\Utility\Validation.php  (check out its date function)

我的疑惑如下:-

1. 为什么允许 逗号 代替月份 仅适用于 29 和 30?

2. 为什么在正则表达式中使用了x20?在 DATE 表达式中使用它有什么必要?

3. 是否有任何日期 standard/rule/specification 我缺少允许使用 29 和 30 而无需提及月份的日期?

任何人都可以帮助理解所有这些事情背后的逻辑吗?

字符 class 中的逗号对正则表达式引擎 有意义 [1,3-9] 匹配 1, (!)、34567 , 89.

您需要删除那个逗号。

此外,模式中有大量冗余分组,只会妨碍模式调试。

这是一个更清晰的正则表达式版本:

^(?:31([-\/.\x20])(?:0?[13578]|1[02])|(?:29|30)([-\/])(?:0?[13-9]|1[0-2]))(?:1[6-9]|[2-9]\d)?\d{2}$|^29([-\/])0?2(?:(?: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])(?:1[6-9]|[2-9]\d)?\d{2}$

regex demo

注意 \x20 匹配一个 space,十进制代码为 32 的字符。使用 \x20 是为了不在模式中引入文字 whitespace这样当您可以向模式添加注释并分成单独的行时,可以使用 x(自由空间)修饰符轻松调试它(请参阅 example)。