Я проверял библиотеку торта и нашел регулярное выражение для даты в ее файле Validation.php. Я использовал его для различных значений даты и обнаружил, что он даже соответствует неправильным значениям даты для некоторых конкретных дат.

Например, он идеально совпадает со следующими датами (что на самом деле должно ): -

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

Но когда я использую неправильное значение даты с 29 и / или 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]))\1|(?:(?:29|30)([-\/])(?:0?[1,3-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})$

Вы можете найти это выражение в каталоге библиотеки cakephp (хотя я использую торт 2.x).

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

enter image description here

Мои сомнения следующие: -

1. Почему запятая вместо месяца разрешена только для 29 и 30?

2. Почему в регулярном выражении используется x20 ? Зачем использовать его в выражении DATE?

3. Есть ли какой-либо стандарт / правило / спецификация даты, который мне не хватает, который позволяет использовать 29 и 30 без упоминания месяца?

Может ли кто-нибудь помочь в понимании логики всех этих вещей?

0
Sumit Parakh 27 Июн 2017 в 08:07
Разве вы не видите запятую в [1,3-9]? Вот почему ставится запятая.
 – 
Wiktor Stribiżew
27 Июн 2017 в 09:28
Я понял это, но я пытался понять, ПОЧЕМУ cakephp будет использовать запятую в первую очередь, если другим придется удалить ее позже?
 – 
Sumit Parakh
27 Июн 2017 в 09:48
1
Это ошибка. Библиотек с регулярными выражениями очень много, и я видел в них такие (и другие) неточности. Это общепринято. В документации есть опечатки (вчера был вопрос по Django). На каком-то сайте говорится, что вы можете использовать [A-z] для сопоставления всех букв ASCII, но на самом деле это неправильно .
 – 
Wiktor Stribiżew
27 Июн 2017 в 09:51
Ok. Спасибо за красивое объяснение и демонстрацию. Я это запомню.
 – 
Sumit Parakh
27 Июн 2017 в 09:55

1 ответ

Лучший ответ

Запятая внутри класса символов значима для механизма регулярных выражений. [1,3-9] соответствует 1, , (!), 3, 4, 5, 6, 7 , 8 и 9.

Вам нужно удалить эту запятую.

Кроме того, в шаблоне есть множество избыточных группировок, которые предотвращают только отладку шаблона.

Вот более чистая версия регулярного выражения:

^(?:31([-\/.\x20])(?: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}$

См. демонстрацию регулярного выражения

Обратите внимание, что \x20 соответствует пробелу, символ с десятичным кодом 32. \x20 используется для того, чтобы не вводить буквальный пробел в шаблон, чтобы его можно было легко отладить с помощью x (freespacing), когда вы можете добавлять комментарии к шаблону и разбивать его на отдельные строки (см. пример ).

2
Wiktor Stribiżew 27 Июн 2017 в 09:40