Zadanie na wyrażenia regularne

Odpowiedz Nowy wątek
2018-02-03 20:45
0

Witam, kolejne zadanie kolejny problem.

Potrzebuje zaczytać dane z pliku tekstowego, a następnie znaleźć wśród nich wyrażenia regularne (do tego momentu nie mam problemów). A następnie na podstawie odczytanej linii zainicjować konstruktor innej klasy... (i tu odpadam)

Ale po kolei:
Pierwszy krok - utwórz klasę wiadomość (jej pola i konstruktor). Klasę Wiadomość utworzyłem trochę okrojoną, wychodzę z założenia że jak rozwiąże problem inicjowania konstruktora linia odczytaną z pliku, to ją rozbuduje do pełnego wymiaru, tak jak jest wymagane w zadaniu).

Klasa Wiadomosc ma pola
int dzien;
int miesiac;
int rok;
String godzina;
//String user; - o to na razie sobie uprościłem
//String ip; - o to na razie sobie uprościłem
//String tekst; - o to na razie sobie uprościłem


public class Wiadomosc {
    int dzien;
    int miesiac;
    int rok;
    String godzina;
    //String user;
    //String ip;
    //String tekst;

    Wiadomosc(int dzien, int miesiac, int rok, String godzina){
        this.dzien = dzien;
        this.miesiac = miesiac;
        this.rok = rok;
        this.godzina = godzina;
    }

}

Wczytaj zawartosc pliku serverLog.txt podziel dane tak, żeby kazda linia inicjowała wspomiany obiekt klasy Wiadomość...
W kolejnym kroku umieść obiekt w kolekcji ArrayList.
Na koniec mam utworzyć trzy metody do wświetlania wszystkich wiadomosci z danego dnia, miesiąca bądx adresu IP.

Przykładowe wiersze z pliku ServerLog.txt:

10 6/23/2006 8:49:09 AM - (not logged in) (10.0.2.143)> Connected, sending welcome message...
11 6/23/2006 8:49:09 AM - (not logged in) (10.0.2.143)> 220-FileZilla Server version 0.9.18 beta

public class WiadomoscTest {

    public static void main(String[] args) {

        ArrayList<String> lista = new ArrayList();

        StringBuilder sb = new StringBuilder();
        File file = new File("ServerLog.txt");
        try{
            FileInputStream fis = new FileInputStream(file);
            int tmp;
            while((tmp = fis.read()) != -1){
                sb.append((char) tmp);
            }
            fis.close();

        } catch (FileNotFoundException e){
            e.printStackTrace();
        } catch (IOException e){
            e.printStackTrace();
        }
        //poniżej okrojony pattern na dzien miesiac rok i godzine.           
        Pattern p = Pattern.compile("([0-9]{1,2})/([0-9]{2})/([0-9]{4}) (([0-9]{1,2}:){2}[0-9]{2} [A-Z]{2})");
        Matcher m = p.matcher(sb.toString());

        for(int i = 0;i <= lista.size();i++){
            while(m.find()){
                          //poniżej mam błąd... czy jest możliwość uruchomienia w ten sposób niejako dynamicznie tworzonego konstruktora klasy Wiadomosc?
                lista.add(new Wiadomosc("Int " +  m.group(1) + "," + "Int " +  m.group(2) + "," + "Int " +  m.group(3) + "," + "String " +  m.group(4)));// = m.group("wiadomosc");
                System.out.println(lista.get(i));

            }
        }
    }
}

Problem mam jak napisałem wyżej w komentarzu, z uruchomieniem konstruktora podając mu jako argumenty odczytane dane.
Pytanie do bardziej doświadczonych, czy dobrze kombinuje, czy to jest w ogóle ślepa uliczka i powinienem pójść w innym kierunku?
Jeżeli tak, to jak się powinno zgodnie ze sztuką rozwiązać taki problem?

Pozostało 580 znaków

2018-02-03 22:54
1

Jak Masz nie mieć błędu, skoro tutaj new Wiadomosc("Int " + m.group(1) + "," + "Int " + m.group(2) + "," + "Int " + m.group(3) + "," + "String " + m.group(4)) Podajesz konstruktorowi jeden argument(Stringa), a on przyjmuje, cztery (trzy inty i String). Musisz sparsować te informacje wyłuskane regexem do odpowiedniego typu i podać konstruktorowi, to będzie działać.


Pozostało 580 znaków

2018-02-04 10:43
0
lion137 napisał(a):

Jak Masz nie mieć błędu, skoro tutaj new Wiadomosc("Int " + m.group(1) + "," + "Int " + m.group(2) + "," + "Int " + m.group(3) + "," + "String " + m.group(4)) Podajesz konstruktorowi jeden argument(Stringa), a on przyjmuje, cztery (trzy inty i String). Musisz sparsować te informacje wyłuskane regexem do odpowiedniego typu i podać konstruktorowi, to będzie działać.

Zmieniłem zgodnie z sugestią i bangla aż miło!

for(int i = 0;i <= lista.size();i++){
            while(m.find()){
                lista.add(String.valueOf(new Wiadomosc(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)),  Integer.parseInt(m.group(3)), m.group(4))));// = m.group("wiadomosc");
                System.out.println(lista.get(i));

Tylko w klasie Wiadomosc trzeba było jeszcze przeciazyc metodę toString();
Wielkie dzięki za pomoc @lion137!

Pozostało 580 znaków

2018-02-05 06:45
0

Może mi ktoś wytłumaczyć dlaczego nie działa mi poniższy regex:
Wszystko działało pięknie do momentu kiedy dodałem w regex grupa("ip") oraz grupa("wiadomosc")
dodam tylko, że obie grupy jeżeli uruchamiam je samodzielnie a nie w ponizszym kodzie działają swietnie...
Ze zmian vs wersja poptrzednia to arrayList jest typu Wiadomosc a nie string, ale to nie powinno mieć wpływu, ponieważ tak jak wspominałem wcześniej bez IP i Wiadomosci dzialało ok.

        Pattern p = Pattern.compile("([0-9]{1,2})/([0-9]{2})/([0-9]{4}) (?<data>([0-9]{1,2}:){2}[0-9]{2} [A-Z]{2}) - (?<user>\\(?([a-z]{2,} ?){2,} ?\\)?) (?<ip>([0-9]{1,3}\\.){3}[0-9]{3}) ?>(?<wiadomosc>[^\n]*)\r?\n");// >(?<wiadomosc>[^\n]*)\r?\n");// pattern wybierający wiadomosc
        Matcher m = p.matcher(sb.toString());

        //System.out.println(m.group(1)+"\n"+m.group(2)+"\n"+m.group(3)+"\n"+m.group(4));

        for(int i = 0;i <= lista.size();i++){
            if(m.find()){// musi być if, bo przy while w jednej iteracji petli przeliatuje przez cały ServerLog, tak, że na drugą interacje już nic nie zostaje
                lista.add(new Wiadomosc(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)),  Integer.parseInt(m.group(3)), m.group("data"), m.group("user"), m.group("ip"), m.group("wiadomosc")));//, m.group("wiadomosc")));// = m.group("wiadomosc");
                System.out.println(lista.get(i));

Pozostało 580 znaków

2018-02-05 10:39

Twój regex nie znajduje takiego ip: 172.16.254.1, za to ten: https://regex101.com/r/JMxdBt/1 tak.
Regex wiadomosc, nie wiem jak on Ci działa, musi być jakaś literówka gdzieś, bo on ma niezamknięty nawias prawy: [^\n]*)\r?\n, Sprawdź to jeszcze raz czy z tą składnią jest wszystko OK.


Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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