Как указано в комментариях ниже, вы используете .matches
, который возвращает true, если вся строка может быть сопоставлена.
В вашем шаблоне ([0-9]{2}[/-])?([0-9]{2}[/-])?([0-9]{4})
он также будет соответствовать только 4 цифрам, поскольку первые 2 группы ([0-9]{2}[/-])?([0-9]{2}[/-])?
являются необязательными из-за знака вопроса ?
, оставляя 3-ю группу ([0-9]{4})
способной совпадать с 4 цифрами.
Вместо этого вы можете использовать чередование для совпадения с форматом даты, когда первые 2 части, включая разделитель, являются необязательными. Или сопоставьте 3 раза 4 цифры.
.*?(?:(?:[0-9]{2}[/-]){2}[0-9]{4}|[0-9]{4}(?:\h[0-9]{4}){2}).*
Объяснение
.*?
Соответствует любому символу, кроме новой строки без жадности
(?:
Группировка без захвата
(?:[0-9]{2}[/-]){2}
Повторите 2 раза, сопоставляя 2 цифры и /
или -
[0-9]{4}
Совпадение 4 цифр
|
или
[0-9]{4}
Совпадение 4 цифр
(?:\\h[0-9]{4}){2}
Повторите 2 раза, сопоставляя горизонтальный символ пробела и 4 цифры
)
Закрыть группу без захвата
.*
Соответствует 0+ раз любому символу, кроме новой строки
Regex demo | Java демо
Например
List<String> list = Arrays.asList(
new String[]{
"10/02/1992 or 1992",
"10/02/1992",
"10/1992",
"02/1992",
"1992",
"1234 5694 7487"
}
);
String regex = ".*?(?:(?:[0-9]{2}[/-]){2}[0-9]{4}|[0-9]{4}(?:\\h[0-9]{4}){2}).*";
for (String str: list) {
if (str.matches(regex)){
System.out.println(str);
}
}
Результат
10/02/1992 or 1992
10/02/1992
1234 5694 7487
Обратите внимание, что в вашем первом паттерне я имею в виду \\s
вместо //s
.
\\s
также будет соответствовать новой строке. Если вы хотите сопоставить один пробел, вы можете просто сопоставить его или использовать \\h
для сопоставления с горизонтальным символом пробела.