Почему эти результирующие данные 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().