Почему мое регулярное выражение для проверки даты не распознает февраль (и другие)? - PullRequest
2 голосов
/ 13 июля 2011

Я работаю над регулярным выражением, которое должно соответствовать григорианским датам месяц-день-год (в javascript), и оно отлично работает для января, марта, мая, июля, августа, октября и декабря (31-дневные месяцы) ) даты, но по какой-то причине, которую я не смог выяснить, она не будет совпадать ни с одной датой из любого другого месяца.

Небольшое объяснение приведенного ниже кода: я настроил его так, чтобы он сначала совпадал с частью дня месяца в месяце, поэтому он не совпадает, например, с 31 февраля. Итак, в настоящее время он соответствует (((31-дневный месяц) THEN (не алфавитно-цифровой символ, захвачен) THEN (день с 1 по 31)) OR ((28-дневный месяц) THEN (не захвачено буквенно-цифровой символ) THEN (день с 1 по 29)) OR ((30-дневный месяц) THEN (не буквенно-цифровой символ, захвачено) THEN (день с 1 по 30))) THEN (ранее захваченный символ) ТОГДА (прошлый или текущий год нашей эры).

Я уверен, что проблема проста, но я просто не вижу ее.

^
(?:
  (?:
    (?:0?[13578]|1[02])
    ([^\dA-Za-z])
    (?:0?[1-9]|1[0-9]|2[0-9]|3[01])
  )
  |
  (?:
    (?:0?2)
    ([^\dA-Za-z])
    (?:0?[1-9]|1[0-9]|2[0-9])
  )
  |
  (?:
    (?:0?[469]|11)
    ([^\dA-Za-z])
    (?:0?[1-9]|1[0-9]|2[0-9]|30)
  )
)
\1
(?:0{0,3}[1-9]|0{0,2}[1-9][0-9]|0?[1-9][0-9]{2}|1[0-9]{3}|200[0-9]|201[01])
$

Ответы [ 2 ]

2 голосов
/ 13 июля 2011

Вы получаете эту ошибку, потому что вы используете \1, что не соответствует последним 2 чередованиям. \1 относится к first ([^\dA-Za-z]) - если он не совпадает, он не может получить год.

Простая альтернатива - (?:\1|\2|\3).

Другой вариант - добавить в начале шаблона (?=\d+([^\dA-Za-z])) и использовать \1 во всех местах. Например:

^
(?=\d+([^\dA-Za-z]))   # capture the separator as \1
(?:
  (?:
    (?:0?[13578]|1[02])
    \1
    (?:0?[1-9]|1[0-9]|2[0-9]|3[01])
  )
  |
  (?:
    (?:0?2)
    \1
    (?:0?[1-9]|1[0-9]|2[0-9])
  )
  |
  (?:
    (?:0?[469]|11)
    \1
    (?:0?[1-9]|1[0-9]|2[0-9]|30)
  )
)
\1
(?:0{0,3}[1-9]|0{0,2}[1-9][0-9]|0?[1-9][0-9]{2}|1[0-9]{3}|200[0-9]|201[01])
$

На заметку: yikes! try Datejs - впечатляющая библиотека дат JavaScript с открытым исходным кодом.

1 голос
/ 13 июля 2011

Ваша проблема - обратная ссылка \1.Это относится к тому, что соответствует группе ([^\dA-Za-z]) в вашем первом чередовании (31 день-месяц).Чтобы соответствовать разделителю второго чередования, вам понадобится \2 и т. Д.

Так что, возможно, вы захотите использовать (?:\1|\2|\3) вместо \1, если только это также не приводит к ошибке в JavaScript.

Наконец, вы знаете, что это все еще не правильно проверяет даты?Подумайте о високосных годах ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...