Почему эти результирующие данные YYYY-MM-DD не работают в Java?
Мой первый вопрос, и я взволнован... Я скрывался с тех пор, как я живу и люблю сайт, однако прошу прощения за любые ошибки, форматирование и т.д....
Я пытаюсь проверить формат строкового поля, содержащего дату на Java. Мы получим дату в строке, я буду проверять ее формат, прежде чем разбирать его в реальном объекте Date. Формат передается в формате YYYY-MM-DD. Однако я застрял на одном из моих тестов, если я перейду в "1999-12-33", тест завершится неудачно (как и в случае с днем 33) с этим неполным шаблоном:
((19|20)\\d{2})-([1-9]|0[1-9]|1[0-2])-([12][0-9]|3[01])
Однако, как только я добавляю символы, выделенные жирным шрифтом ниже, он проходит тест (но не должен)
((19|20)\\d{2})-([1-9]|0[1-9]|1[0-2])-(0[1-9]|[1-9]|[12][0-9]|3[01])
* дополнительная заметка, я знаю, что могу изменить 0[1-9]|[1-9]
на 0?[1-9]
, но я хотел разбить все до самого простого формата, чтобы попытаться найти, почему это не работает.
Вот тест лома, который я собрал для запуска всех разных сценариев даты:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class scrapTest {
public scrapTest() {
}
public static void main(String[] args) {
scrapTest a = new scrapTest();
boolean flag = a.verfiyDateFormat("1999-12-33");
}
private boolean verfiyDateFormat(String dateStr){
Pattern datePattern = Pattern.compile("((19|20)\\d{2})-([1-9]|0[1-9]|1[0-2])-(0[1-9]|[1-9]|[12][0-9]|3[01])");
Matcher dateMatcher = datePattern.matcher(dateStr);
if(!dateMatcher.find()){
System.out.println("Invalid date format!!! -> " + dateStr);
return false;
}
System.out.println("Valid date format.");
return true;
}
}
Я программировал в течение ~ 10 лет, но чрезвычайно новичок в Java, поэтому, пожалуйста, не стесняйтесь объяснять что-либо как элементарное, как вы сочтете нужным.
Ответы
Ответ 1
Я думаю, потому что вы используете dateMatcher.find()
, а не dateMatcher.matches()
. Первый ищет совпадение, последний пытается сопоставить всю строку. См. Страницу API. Таким образом, в основном первые 3 из 33 будут совпадать с [1-9], которые вы только что добавили, а второй 3 не будет соответствовать никчем, но метод все равно возвращает true.
Ответ 2
(0 [1-9] | [1-9] | [12] [0-9] | 3 [01])
второй случай, [1-9], выглядит как часть, которая выполняется как , у вас нет теста для конца строки.
Это соответствует 1999-12-3, а не 1999-12-33
Ответ 3
Как насчет использования SimpleDateFormat для этого?
Date d = new SimpleDateFormat("yyyy-MM-dd").parse(somestring);
if (d == null) {
// somestring is not a Date
} else {
// d is the Date
}
Документы для SimpleDateFormat
Ответ 4
На самом деле не ответ на вопрос, а предложение: напишите более простое регулярное выражение, а затем выполните числовую проверку в Java, а не в вашем регулярном выражении:
(\\d{4})-(\\d{2})-(\\d{2})
Совместите это со своим входом, извлеките соответствующие группы и преобразуйте в целые числа, затем проверьте год, месяц и день, чтобы убедиться, что они находятся в допустимом диапазоне.
Ответ 5
Как сказал Брам, ваш шаблон находит часть даты для соответствия, чтобы соответствовать всей входной строке, используйте:
if (!dateMatcher.matches()) {
вместо find()
.