Wyrażenia regularne do walidacji dat wczytanych z pliku

0

Cześć! Mam zadanie, żeby wczytać wszystkie daty z pliku. Przykładowy plik ma zawartość:

2007-01-12Jakis txt2008-01-31 xxx 2008-02-29 2008-15-10 2008-19-45 2009-05-01
20999-11-11 pppp 2001-00-01 09-01-01 2001-01-00 2009-01-111 2009-02-29 1998-11-11

W sumie, to poradziłem sobie z wszystkim oprócz jednego zagadnienia. Użyłem wyrażenia regularnego:

String regexp = "[1-9][0-9][0-9][0-9][-][0-1][0-9][-][0-3][0-9]";

W dalszej części programu jest sprawdzane, czy miesiąc nie jest większy niż 12, czy liczba dni się zgadza dla danego miesiąca itd. Jednak prawidłowy wynik powinien być:

2007-01-12 2008-01-31 2008-02-29 2009-05-01 1998-11-11

A u mnie jest:

2007-01-12 2008-01-31 2008-02-29 2009-05-01 2009-01-11 1998-11-11 

Program zaakceptował "2009-01-111" jako "2009-01-11", a powinien potraktować jako przekroczenie liczby dni i nie zaakceptować tej daty. Przyznam, że nie mam pomysłu jak to rozwiązać. Za ewentualne wskazówki z góry dziękuję.

0

dodaj $ na końcu wyrażenia

0
String regexp = "[1-9][0-9][0-9][0-9][-][0-1][0-9][-][0-3][0-9]$";

Zwraca wtedy jedynie: 1998-11-11

0

$ matchuje do końca linii, więc znajdzie tylko tekst na końcu linii. \b matchuje do końca wyrażeń, więc znajdzie Ci prawie wszystko, co chciałeś, ale nie tekst z "2007-01-12Jakis txt2008-01-31".

Najlepszym rozwiązaniem, jakie mi na szybko przychodzi na myśl, jest \D?([1-9][0-9][0-9][0-9][-][0-1][0-9][-][0-3][0-9])\D?, czyli zero lub jedna nie-cyfra, grupa matchująca jaką chciałeś, zero lub jedna nie-cyfra. Jeśli nie masz obsługi \D, to możesz to zastąpić [^0-9].

0

Wkleję istotny fragment programu:

...
String regexp = "\\D?([1-9][0-9][0-9][0-9][-][0-1][0-9][-][0-3][0-9])\\D?";
        Pattern pattern = Pattern.compile(regexp);
        Matcher matcher = pattern.matcher(scannerContent);
        String result = "";
        boolean found = matcher.find();
        if (!found)
            result += "Nie znaleziono żadnej daty";
        else
            do {
                System.out.println("matcher " + matcher.group());
...

println wyświetla

matcher 2007-01-12J
matcher t2008-01-31x
matcher x2008-02-29
matcher 2008-15-10
matcher 2009-05-01
matcher p2001-00-01
matcher 2001-01-00
matcher 2009-01-11
matcher 2009-02-29
matcher 1998-11-11

Czyli ten "2009-01-111" przechodzi cały czas dalej jako "2009-01-11"

0

Musisz używać wyrażeń regularnych?

        String input = "2007-01-12Jakis txt2008-01-31 xxx 2008-02-29 2008-15-10 2008-19-45 2009-05-01\n 20999-11-11 pppp 2001-00-01 09-01-01 2001-01-00 2009-01-111 2009-02-29 1998-11-11";
        SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd");
        parser.setLenient(false);
        int index = 0;
        Date date = null;
        ParsePosition pos = new ParsePosition(0);
        
        while(index < input.length())
        {
            while(index < input.length() && !Character.isDigit(input.charAt(index)))
            {
                index++;
            }
            pos = new ParsePosition(index);
            date = parser.parse(input,pos);
            if(date != null)
            {
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(date);
                int year = calendar.get(Calendar.YEAR);
                if(year >= 1000 && year <= 9999)
                {
                    System.out.println(parser.format(date));
                }
                index = pos.getIndex();
            }
            else
            {
                index = pos.getIndex() + 1;
            }
        }
0

Jest to zadanie z podstaw programowania na jednej uczelni. W treści zadania wyrażenia regularne są jako wskazówka, nie jako wymóg. Prawdopodobnie Twoje rozwiązanie jest zbyt zaawansowane i wykładowca zakładał coś z wyrażeniami regularnymi, jednak ja nie zaliczam teraz tego przedmiotu tylko robię te zadania dla utrwalenia podstaw :) Dzięki, bo Twoje rozwiązanie też mi sporo dało jeśli chodzi o spojrzenie na pracę z datami, formatami dat.

1 użytkowników online, w tym zalogowanych: 0, gości: 1