Регулярное выражение для соответствия допустимым датам

С Коллекции Eclipse (ранее коллекции GS ) будет работать метод removeIf, определенный на MutableCollection :

MutableList list = Lists.mutable.of(1, 2, 3, 4, 5);
list.removeIf(Predicates.lessThan(3));
Assert.assertEquals(Lists.mutable.of(3, 4, 5), list);

С синтаксисом Java 8 Lambda это можно записать следующим образом:

MutableList list = Lists.mutable.of(1, 2, 3, 4, 5);
list.removeIf(Predicates.cast(integer -> integer < 3));
Assert.assertEquals(Lists.mutable.of(3, 4, 5), list);

Необходим вызов Predicates.cast(), потому что по умолчанию removeIf метод был добавлен на интерфейс java.util.Collection в Java 8.

Примечание: я являюсь коммиттером для коллекций Eclipse .

63
задан stema 28 November 2011 в 15:28
поделиться

9 ответов

Это не соответствующее использование регулярных выражений. Вы были бы более обеспеченным использованием

[0-9]{2}/[0-9]{2}/[0-9]{4}

и затем проверка диапазонов на высокоуровневом языке.

129
ответ дан Chris Conway 24 November 2019 в 16:03
поделиться

Немного отличающийся подход, который может или не может быть полезен для Вас.

я нахожусь в php.

проект, которого это касается, никогда не будет иметь даты до 1-го января 2008. Так, я беру оценочную 'дату' и использую strtotime (). Если ответ> = 1199167200 тогда, у меня есть дата, которая полезна для меня. Если что-то, что не похоже на дату, вводится-1, возвращается. Если пустой указатель вводится, он действительно возвращает сегодняшнее число даты, таким образом, Вам действительно нужна проверка на непустую запись сначала.

Работы для моей ситуации, возможно, Ваша также?

-1
ответ дан Humpton 24 November 2019 в 16:03
поделиться

Если бы Вы собираетесь настоять на том, чтобы делать это с регулярным выражением, я рекомендовал бы что-то как:

( (0?1|0?3| <...> |10|11|12) / (0?1| <...> |30|31) |
  0?2 / (0?1| <...> |28|29) ) 
/ (19|20)[0-9]{2}

Это могло бы позволять читать и понять.

0
ответ дан Chris Conway 24 November 2019 в 16:03
поделиться

Я знаю, что это не отвечает на Ваш вопрос, но почему Вы не используете стандартную программу обработки даты, чтобы проверить, является ли это допустимая дата? Даже если Вы изменяете regexp с отрицательным предварительным утверждением как (?! 31/0? 2) (т.е., не соответствуйте 31/2 или 31/02), у Вас все еще будет проблема принятия 29 02 на не високосные годы и о единственном формате даты разделителя.

проблема не легка, если Вы хотите действительно проверить дату, проверьте этот поток форума .

Для примера или лучшего пути, в C#, проверка эта ссылка

при использовании другой платформы/языка сообщи нам

1
ответ дан Vinko Vrsalovic 24 November 2019 в 16:03
поделиться

Regex не был предназначен для проверки диапазонов числа (это число должно быть от 1 до 5, когда число, предшествующее ему, оказывается, 2 и число, предшествующее, который, оказывается, ниже 6). Просто ищите шаблон размещения чисел в regex. Если необходимо проверить, качества даты, поместите ее в дату, возражают js/c#/vb и опрашивают числа там.

1
ответ дан DevelopingChris 24 November 2019 в 16:03
поделиться

Perl развернул использование Примечания версии

/x модификатор.

/^(
      (
        ( # 31 day months
            (0[13578])
          | ([13578])
          | (1[02])
        )
        [\/]
        (
            ([1-9])
          | ([0-2][0-9])
          | (3[01])
        )
      )
    | (
        ( # 30 day months
            (0[469])
          | ([469])
          | (11)
        )
        [\/]
        (
            ([1-9])
          | ([0-2][0-9])
          | (30)
        )
      )
    | ( # 29 day month (Feb)
        (2|02)
        [\/]
        (
            ([1-9])
          | ([0-2][0-9])
        )
      )
    )
    [\/]
    # year
    \d{4}$

  | ^\d{4}$ # year only
/x

Оригинал

^((((0[13578])|([13578])|(1[02]))[\/](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/](([1-9])|([0-2][0-9])|(30)))|((2|02)[\/](([1-9])|([0-2][0-9]))))[\/]\d{4}$|^\d{4}$
3
ответ дан Brad Gilbert 24 November 2019 в 16:03
поделиться

Кажется, что Вы перенапрягаете regex с этой целью. То, что я сделал бы, использовать regex, чтобы соответствовать нескольким форматам даты и затем использовать отдельную функцию для проверки значений полей даты, так извлеченных.

4
ответ дан Wedge 24 November 2019 в 16:03
поделиться

Версия Perl 6

rx{
  ^

  $<month> = (\d ** 1..2)
  { $<month> <= 12 or fail }

  '/'

  $<day> = (\d ** 1..2)
  {
    given( +$<month> ){
      when 1|3|5|7|8|10|12 {
        $<day> <= 31 or fail
      }
      when 4|6|9|11 {
        $<day> <= 30 or fail
      }
      when 2 {
        $<day> <= 29 or fail
      }
      default { fail }
    }
  }

  '/'

  $<year> = (\d ** 4)

  $
}

После использования этого для проверки входа, значения доступны в $/ или индивидуально как $<month>, $<day>, $<year>. (это - просто синтаксис для доступа к значениям в $/ )

Никакая попытка не была предпринята для проверки года, или что он не соответствует 29-му из Feburary на не високосные годы.

1
ответ дан Brad Gilbert 24 November 2019 в 16:03
поделиться

Удобная в сопровождении версия Perl 5.10

/
  (?:
      (?<month> (?&mon_29)) [\/] (?<day>(?&day_29))
    | (?<month> (?&mon_30)) [\/] (?<day>(?&day_30))
    | (?<month> (?&mon_31)) [\/] (?<day>(?&day_31))
  )
  [\/]
  (?<year> [0-9]{4})

  (?(DEFINE)
    (?<mon_29> 0?2 )
    (?<mon_30> 0?[469]   | (11) )
    (?<mon_31> 0?[13578] | 1[02] )

    (?<day_29> 0?[1-9] | [1-2]?[0-9] )
    (?<day_30> 0?[1-9] | [1-2]?[0-9] | 30 )
    (?<day_31> 0?[1-9] | [1-2]?[0-9] | 3[01] )
  )
/x

Можно получить элементы по имени в этой версии.

say "Month=$+{month} Day=$+{day} Year=$+{year}";

(Никакая попытка не была предпринята для ограничения значений в течение года.)

13
ответ дан Brad Gilbert 24 November 2019 в 16:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: