Регулярное выражение отлично проверяется с помощью онлайн-инструмента, но не в приложении Java

У меня есть это регулярное выражение, используемое в Java, как показано ниже:

private static final String DATE_TIME_REGEX = "^(20[1-5]\\d)-(0?[1-9]|1[012])-(0?[1-9]|[12]\\d|3[01])\\s([0-1]\\d)|(2[0-3]):([0-5]\\d):([0-5]\\d)$";

public static boolean validateDate(String dateStr) {
    return dateStr.matches(DATE_TIME_REGEX);
}

... для проверки даты в этом формате:

private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    String formattedDate = dateTimeFormatter.format(LocalDateTime.now());

...с помощью этого онлайн-инструмента

https://regexr.com/

... где добавление этого регулярного выражения:

^(20[1-5]\d)-(0?[1-9]|1[012])-(0?[1-9]|[12]\d|3[01])\s([0-1]\d)|(2[0-3]):([0-5]\d):([0-5]\d)$

... отлично работает для проверки строки даты, например:

2022-11-02 00:00:00

... но не проходит проверку (без указания особенностей) с использованием вышеупомянутого кода проверки в java

Чтобы исключить единственное предостережение, которое я могу придумать: при добавлении кода из онлайн-инструмента в код java я должен добавить дополнительную \ перед другими обратными косыми чертами в шаблоне регулярного выражения при перемещении его из онлайн-инструмента, т. е. \d and \s -> \\d and \\s. Однако я очень сомневаюсь, что это проблема

🤔 А знаете ли вы, что...
Java позволяет создавать графические интерфейсы пользователя с помощью библиотеки Swing.


1
56
1

Ответ:

Решено

Узор содержит одну группу и чередование, которые выглядят неуместными:

^(20[1-5]\d)-(0?[1-9]|1[012])-(0?[1-9]|[12]\d|3[01])\s([0-1]\d)|(2[0-3]):([0-5]\d):...
                                                      ^ HERE > ^

Это делает ваш текущий шаблон совпадающимregex101

  • ЛИБО левая часть чередования от запуска до [0-1]\d часовой части
  • ИЛИ правая часть от 2[0-3] часовой части до конца

Использование этого с matches() не может работать, потому что оно сопоставляется с полной строкой:

public boolean matches()
Попытки сопоставить весь регион с образцом.
Если совпадение будет успешным, можно будет получить дополнительную информацию...


Рефакторинг путем исправления структуры работает нормально (при использовании matches^ и $ избыточны).

20[1-5]\d-(?:0?[1-9]|1[012])-(?:0?[1-9]|[12]\d|3[01])\s(?:[0-1]\d|2[0-3]):[0-5]\d:[0-5]\d

Посмотрите эту демонстрацию Java на tio.run или демоверсию на regex101 (объяснение шаблона и генератор кода)