Поиск лучшего шаблона регулярных выражений для формата даты - PullRequest
0 голосов
/ 26 июня 2019

Я должен проверить, соответствует ли строка определенному шаблону.Шаблон выглядит следующим образом:

dd.mm.yyyy HH:mm;score;duration
  • обратите внимание на пробел между yyy и HH
  • , представляющий собой целое значение
  • длительность, являющуюся двойным значением

Как построить шаблон регулярного выражения, касающийся вышеуказанной проблемы?Что я пропустил в своем коде или сделал неправильно?

В основном меня смущают специальные символы, такие как точка с запятой, двоеточие, пробел и то, когда следует использовать \ или \\* 1017.*

public HighscoreEntry(String data) {

    String pattern= "^(3[01]|[12][0-9]|0?[1-9])\\.\\(1[0-2]|0?[1-9])\\.\\(20[0-9]{2})\\s\\(2[0-4]|[01][0-9])\\:\\(5[0-9]|[0-4][0-9]\\;\\d+\\;\\d*\\.\\d+$"; 

    if(data.matches(pattern)){
...

Ответы [ 2 ]

0 голосов
/ 26 июня 2019

Поскольку вопрос таков: Нахождение лучшего шаблона регулярных выражений, а не Что такое лучший шаблон регулярных выражений, я собираюсь ответить на него. Техника, которую я использую, является более или менее подходом «разделяй и властвуй».

Сначала найдите разделители. Тогда вы можете построить свой шаблон так:

String pattern = field1() + ";" + field2() + "|" + field3(); 

Тогда ваши поля могут иметь типы данных. Обратите внимание, что не каждый (строковое представление) домен является регулярным! Так что проверь это первым. В вашем примере вы хотите что-то вроде этого:

String pattern = intPattern(2) + "\\." + intPattern(2) + "\\." + intPattern(4)
               + " " + intPattern(2) + ":" + intPattern(2)
               + ";" + intPattern() + ";" + doublePattern();

Где intPattern(n) - шаблон для целого числа без знака с точно n цифрами, intPattern() - шаблон для произвольного числа цифр.

Преимущества:

  1. Вы можете проверить шаблоны по отдельности.
  2. Вы не получите сверхдлинное регулярное выражение, которое выглядит как беспорядок

Но ваш пример предполагает, что вы хотите больше, чем просто проверка шаблона. То, что вы хотите, это семантика. Вы хотите проверить, что dd.MM.yyyy является действительной датой. Это невозможно, потому что язык правильных дат (в общем) не является регулярным. Если вы рассматриваете только конечное подмножество дат (например, с 1990 по 2400 год), вы можете сделать это (конечные языки всегда регулярны), но это будет беспорядок.

0 голосов
/ 26 июня 2019

Более спокойное выражение

^\d{2}\.\d{2}\.\d{4} \d{2}:\d{2};\d+;\d.\d*$

И тот, который принимает во внимание возможные значения даты и времени

^[0-3][0-9]\.[0-1][0-9]\.\d{4} [0-2][0-9]:[0-5][0-9];\d+;\d*.\d*$

Чтобы использовать их в строке Java, каждый \ должен быть экранирован \, поэтому \ -> \\

Я не проверял шаблоны, поэтому могут существовать некоторые опечатки

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