środa, 31 sierpnia 2011

Dziennik Ustaw v0.1

Wstępna wersja aplikacji pobierającej informacje o najnowszych numerach dziennika ustaw. Wyświetla numery i daty wydania ostatnich 10 numerów dziennika ustaw. Informacje aktualizowane są co 5 minut.

DOWNLOAD

Wymagana Java 7

Zabawa z regexem - wyrażenia regularne

Śledzę czasem Dziennik Ustaw czekając na interesujące mnie rozporządzenie. Jednak Rządowe Centrum Legislacji nie udostępnia kanału RSS (przynajmniej o takowym nie wiem).

Prostym rozwiązaniem tego problemu jest napisanie aplikacji co kilka minut sprawdzającej czy nie pojawił się nowy DU. Do tego celu użyjemy Regex'a czyli wyrażeń regularnych.

Obsługa wyrażeń regularnych w javie składa się z klas Pattern oraz Matcher. Klasa Pattern, metodą static Pattern compile(String regex), tworzy wzorzec na podstawie podanego w argumencie wyrażenia regularnego. Instancję klasy Matcher tworzymy przy użyciu metody klasy Pattern Matcher matcher(CharSequence input).

Następnie używamy metod boolean find() oraz String group() klasy Matcher aby, odpowiednio, odnaleźć następną pasującą subsekwencję oraz uzyskać ją w formie String'a.

Na przykładzie strony http://www.dziennikustaw.gov.pl/ wypisujemy na ekran numery oraz daty ukazania się ostatnich 10 numerów dziennka ustaw.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main
{
    public static void main(String[] args) throws MalformedURLException, IOException
    {
        /* POBRANIE ŹRÓDŁA STRONY*/
        URL url = new URL("http://dziennikustaw.gov.pl/");
        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
        
        StringBuilder buff = new StringBuilder();
        
        String line;
        while((line = in.readLine())!=null)
        {
            buff.append(line);
            buff.append("\n");
        }
        String str = buff.toString();
        
        in.close();
        
        /* PARSOWANIE ŹRÓDŁA */
        Pattern pattNumer = Pattern.compile("<td class=\"c\">([0-9]{1,3})</td>");
        Matcher matchNumer = pattNumer.matcher(str);
        
        Pattern pattData = Pattern.compile("<td class=\"c\">([0-9]{4}-[0-9]{2}-[0-9]{2}) ([0-9]{2}:[0-9]{2}:[0-9]{2})<br />"); //br bez spacji
        Matcher matchData = pattData.matcher(str);
        
        int i=0;
        
        while(matchNumer.find() && matchData.find() && i<10)
        {
            System.out.println(matchNumer.group(1)+" "+matchData.group(1)+" "+matchData.group(2));
            
            i++;
        }
    }
}
W wyniku działania programu otrzymamy:
run:
179 2011-08-30 16:56:35
178 2011-08-29 18:44:54
177 2011-08-26 19:57:05
176 2011-08-26 19:43:00
175 2011-08-25 18:21:44
174 2011-08-23 17:42:06
173 2011-08-22 17:21:39
172 2011-08-19 17:10:41
171 2011-08-18 18:36:57
170 2011-08-18 18:31:47
BUILD SUCCESSFUL (total time: 0 seconds)
A więc mamy wszystkie potrzebne dane. Jest to dobry zalążek do pisania większej aplikacji.


EDIT: Poprawione, wydobywanie danych przy użyciu group() zamiast replaceAll().