Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 18
  1. #1

    [Java: Regexp] Controllare stringhe estratte da un file

    Salve a tutti,
    sono veramente una schiappa con le Regexp quindi chiedo aiuto qui nel forum!
    La situazione è la seguente:
    Apro un file, lo scorro con una readline() e ad ogni linea dovrei controllare(true/false) che la linea sia cosi composta
    codice:
    String|String|int|int|int|String
    Le prime tre stringhe partendo da sinistra e l'ultima potrebbero essere composte da lettere(maiuscole/minuscole), numeri e possibili spazi (anche doppi) sia all'interno che all'inizio e alla fine e tabulazioni.

    il primo intero non ha vincoli, può essere qulunque numero positivo, 0 compreso

    il secondo intero dovrebbe essere compreso fra 1900 e 2100 (inclusi)

    il terzo intero dovrebbe essere compreso fra 0 e 1000 (inclusi)

    I controlli sui valori degli interi è trascurabile, più comodo, ma trascurabile se complica troppo la stesura dell'espressione.
    Qualcuno sarebbe cosi gentile da aiutarmi a scriverla?
    Grazie mille in anticipo, buona giornata

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [Java: Regexp] Controllare stringhe estratte da un file

    Originariamente inviato da -MaVeRiK86-
    codice:
    String|String|int|int|int|String
    Le prime tre stringhe partendo da sinistra e l'ultima potrebbero essere composte da lettere(maiuscole/minuscole), numeri e possibili spazi (anche doppi) sia all'interno che all'inizio e alla fine e tabulazioni.

    il primo intero non ha vincoli, può essere qulunque numero positivo, 0 compreso

    il secondo intero dovrebbe essere compreso fra 1900 e 2100 (inclusi)

    il terzo intero dovrebbe essere compreso fra 0 e 1000 (inclusi)

    I controlli sui valori degli interi è trascurabile, più comodo, ma trascurabile se complica troppo la stesura dell'espressione.
    Qualcuno sarebbe cosi gentile da aiutarmi a scriverla?
    Se pensavi di fare una unica regex che possa validare anche il range di quei valori, allora no, te lo sconsiglio.

    Le regex trattano caratteri ... non valori numerici. Pertanto fare una regex che possa validare anche quei range particolari diventerebbe molto complesso e fumoso.

    Tanto per darti una idea: per validare una stringa che contiene un numero da 0 a 255, la regex dovrebbe essere:

    1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5]

    Proprio perché tratta sequenze di caratteri ... non "sa" nulla di valori numerici e quindi bisogna fare i vari casi delle possibili sequenze e range.

    Se vuoi puoi validare "blandamente" quei valori numerici (es. per 1900-2100 verificare che ci siano sempre 4 digit) ma poi devi parsare il valore con parseInt() di Integer e verificare il range. E questo vuol dire che devi estrarre dei "gruppi" e quindi devi usare Pattern/Matcher ... non un semplice matches() di String.

    Se ti va bene così, ok puoi fare una regex unica.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Intanto ti ringrazio per la risposta!
    Infatti ho scritto che il controllo specifico sui valori era trascurabile nel caso avesse reso la cosa incasinata, non è importante, lo controllo dopo direttamente nella classe!
    Potresti invece aiutarmi a stendere la sola espressione che controlli che il campo sia in quel formato che ho scritto?
    Grazie mille!

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da -MaVeRiK86-
    Potresti invece aiutarmi a stendere la sola espressione che controlli che il campo sia in quel formato che ho scritto?
    Faccio l'esempio di String|int. Il primo accetta lettere/numeri/spazi/tabulazioni. Il secondo accetta 4 digit (come nel caso 1900-2100).

    String strPattern = "[a-zA-Z0-9 \\t]+\\|(\\d{4})";

    Nota la "classe" di caratteri racchiusa tra [ ] con il + che segue che vuol dire "uno o più". Nota il \\| (il pipe è speciale, va fatto l'escape se vuoi proprio matchare un pipe!) e nota il "gruppo" racchiuso tra ( ) per i 4 digit.

    Prima crei un java.util.regex.Pattern, compilando la regex, poi usi java.util.regex.Matcher e in particolare il suo matches(). Se ti dice true, il formato corrisponde e quindi puoi invocare group(1) di Matcher per prendere il testo matchato dal gruppo 1 (quello dei 4 digit).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Grande, grazie mille gentilissimo ora la provo!

  6. #6
    Rispolvero ancora una volta questa domanda e ti rompo ancora un po' le scatole
    La regexp da te postata è valida per la situazione in cui mi trovo una stringa composta da
    codice:
    String|int
    ad esempio:
    Kobol’s Last Gleaming: Part 1|2005
    Se io invece volessi espanderla per controllare l'intera stringa, ossia
    String|String|int|int|int|String
    Senza nessun particolare controllo sugli interi (che siano a una cifra o quattro cifre è indifferente, lo controllo dopo) sarebbe corretta questa?
    String strPattern = "[a-zA-Z0-9 \\t]\\|[a-zA-Z0-9 \\t]\\|(\\d{*})(\\d{*})(\\d{*})\\[a-zA-Z0-9 \\t]";
    Devo aver scritto una cavolata immane..

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da -MaVeRiK86-
    Se io invece volessi espanderla per controllare l'intera stringa, ossia
    String|String|int|int|int|String

    String strPattern = "[a-zA-Z0-9 \\t]\\|[a-zA-Z0-9 \\t]\\|(\\d{*})(\\d{*})(\\d{*})\\[a-zA-Z0-9 \\t]";
    Devo aver scritto una cavolata immane..
    È sbagliata sia a livello tecnico della espressione sia come significato della espressione (che non fa quello che vorresti).

    Io nel mio esempio ho messo [a-zA-Z0-9 \\t]+, vedi il + finale? Tu già questo non l'hai messo. Poi hai messo {*} ed è sbagliato. Se vuoi "uno o più digit", allora basta \\d+.
    I "quantificatori" con { } sono solo in una delle forme:

    codice:
    X{n}  	X, exactly n times
    X{n,} 	X, at least n times
    X{n,m} 	X, at least n but not more than m times
    dove n e m sono numeri, come ripeto non puoi mettere *.

    Infine non hai messo il match del pipe | tra i 3 int e alla fine hai messo un \\[ che non è quello che volevi sicuramente.

    E un suggerimento finale: quando la regex è lunga/complessa, ti conviene spezzarla in più String semplici e poi concatenarli.

    codice:
    final String wordExpr = "[a-zA-Z0-9 \\t]+";
    final String pipeExpr = "\\|";
    final String intExpr = "(\\d+)";
    
    String tuaExpr = wordExpr + pipeExpr + ..........;
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  8. #8

    Pensavo di aver capito e ho provato (infatti scusami del ritardo della risposta), ma mi sbagliavo..mi arrendo, ti posto il casino che ho fatto!
    codice:
    String serial = "[a-zA-Z0-9 \\t]+";
    String separatore = "\\|";
    String titolo = "[a-zA-Z0-9 \\t]+";
    String separatore = "\\|";
    String stagione = "(\\d+)";
    String separatore = "\\|";
    String anno = "(\\d+)";
    String separatore = "\\|";
    String id = "(\\d+)";
    String separatore = "\\|";
    String genere = "[a-zA-Z0-9 \\t]+";
    String regexp = serial + separatore + titolo + separatore + stagione + separatore + anno + separatore + id + separatore + genere;
    dopo, quando scorro il file
    codice:
    Pattern p = Pattern.compile(regexp);
    while(lunghezza file) {
        riga = readline;
        Matcher m = p.matcher(riga);
        if(m.matches()) {
             //gestisco e aggiungo il record al catalogo
        }
    }
    Grazie mille per la pazienza!!!

  9. #9
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da -MaVeRiK86-
    ti posto il casino che ho fatto!
    codice:
    String serial = "[a-zA-Z0-9 \\t]+";
    String separatore = "\\|";
    String titolo = "[a-zA-Z0-9 \\t]+";
    String separatore = "\\|";
    String stagione = "(\\d+)";
    String separatore = "\\|";
    String anno = "(\\d+)";
    String separatore = "\\|";
    String id = "(\\d+)";
    String separatore = "\\|";
    String genere = "[a-zA-Z0-9 \\t]+";
    String regexp = serial + separatore + titolo + separatore + stagione + separatore + anno + separatore + id + separatore + genere;
    Hai dichiarato più volte 'separatore', non va bene ovviamente. Se per ognuno dei vari campi (nonostante magari uno abbia lo stesso "formato" di altri) vuoi definire una apposita variabile String, ok va bene. Ma dichiara solo 1 variabile di separatore.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  10. #10
    Grazie al tuo preziosissimo aiuto, ci siamo quasi!!!!
    Ho provato con:
    codice:
    String str = "[a-zA-Z0-9 \\t]+";
    String sep = "\\|";
    String digit = "(\\d+)";
    String regexp = str + sep + str + sep + digit + sep + digit + sep + digit + sep + str;
    
    //finto catalogo di esempio
    String [] record = new String[5];
    record[0] = "Battlestar Galactica|Kobol’s Last Gleaming: Part 1|1|2004|12|Sci-Fi";
    record[1] = "Friends|The One Where Joey Speaks French|10|2004|231|Sit-Com";
    record[2] = "Lost|Exposé|3|2007|63|Drama";
    record[3] = "NCIS ciao|Trojan Horse|4|2007|93|Crime Investigation";
    record[4] = "The Simpson|Squadra Homer|7| 2005   |10 |Cartoon";
    Pattern p = Pattern.compile(regexp);
    
    //scorro il catalogo e controllo gli episodi
    for(int i = 0; i < record.length; i++) {
    	Matcher m = p.matcher(record[i]);
    	if(m.matches())
    		System.out.println("La riga " + i + " è corretta > " + record[i]);
    	else
    		System.out.println("La riga " + i + " NON è corretta > " + record[i]);
    }
    E l'output è:
    codice:
    La riga 0 NON è corretta > Battlestar Galactica|Kobol’s Last Gleaming: Part 1|1|2004|12|Sci-Fi
    La riga 1 NON è corretta > Friends|The One Where Joey Speaks French|10|2004|231|Sit-Com
    La riga 2 NON è corretta > Lost|Exposé|3|2007|63|Drama
    La riga 3 è corretta > NCIS ciao|Trojan Horse|4|2007|93|Crime Investigation
    La riga 4 NON è corretta > The Simpson|Squadra Homer|7| 2005   |10 |Cartoon
    A quanto ho capito leggendo dall'output in relazione agli episodi [a-zA-Z0-9 \\t]+ non include anche caratteri accentati, punteggiatura e cose simili, come si può modificarla in questo caso?

    Secondo dubbio: nel caso mi trovi una situazione come: | 2005 |10 |
    Sono sempre numeri ma con degli spazi in mezzo (è prevedibile che nel test ci siano righe simili) e (\\d+) in questo caso non me lo riconosce più.E' risolvibile?Avevo pensato ad un replaceAll che mi tolga tutti gli spazi, ma così facendo farei un casino con i titoli e i serial..

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.