Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Tra audio e AI: la ricetta di Qualcomm per l'agentic AI
Tra audio e AI: la ricetta di Qualcomm per l'agentic AI
Snapdragon Soung Gen 2 è la piattaforma Qualcomm per i dispositivi audio sempre più integrati nel mondo dell'intelligenza artificiale: al prorpio interno tanta potenza elaborativa per gestire al meglio le necessità d'uso dell'agentic AI
Qualcomm annuncia la nuova generazione di SoC Snapdragon 8 Elite Gen 6
Qualcomm annuncia la nuova generazione di SoC Snapdragon 8 Elite Gen 6
In occasione del proprio Snapdragon Summit Qualcomm annuncia i due nuovi chip per dispositivi mobile di fascia alta che entreranno nel mercato nel corso del 2027: tanta potenza a disposizione per elaborazioni di intelligenza artificiale sempre più complesse
realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole!
realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole!
Hogwarts arriva in fascia media grazie a realme, con una special edition che unisce la Quadra Light-Sensing Color-changing Tech, un baule in stile Hogwarts Express pieno di collezionabili e una scheda tecnica sostanzialmente identica al 16 Pro di partenza: ecco cosa cambia davvero, come si comporta nell'uso quotidiano e quanto vale in base al prezzo di 699,99 euro
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 10-07-2011, 16:02   #1
DeltaDirac
Senior Member
 
L'Avatar di DeltaDirac
 
Iscritto dal: Jan 2007
Città: Firenze
Messaggi: 2906
[JAVA - regex]

Ciao a tutti i Java-Guru

Sto cercando di controllare il formato di due file di testo con la libreria java.util.regex, al momento senza grosse soddisfazioni

Il primo file contiene una serie di dati nel seguente formato:


Amico1 Amico2 distanza12 Amico3 distanza13 Amico4 distanza14
Amico3 Amico5 distanza35
Amico5 Amico6 distanza56 Amico7 distanza57


esempio:

Anton.Luca Bianca 150 Claudio 14 Ciro 280
Claudio Francesco 45
Francesco Giovanni 100 Luca 50 Piero 200


Non ho molta confidenza con le espressioni regolari ed ho qualche difficoltà a concatenare i controlli sui set di caratteri di input.

Ho tentato di costruire una classe ( controlloPattern ) che riuscisse a verificare se il file di input aderisce allo standard oppure o no, ma l'unica cosa che son riuscito ad ottenere è una "verifica per parti" ovvero son riuscito a leggere o solo i nomi o solo le distanze ma non OK se la verifica è positiva:

Codice:
public class controlloPattern {
 
        String regex = "[A-Za-z.]+[a-zA-Z0-9]{2,3}";
        
        String input = "Anton.Luca Bianca 150 Claudio 14 Ciro 280 Claudio Francesco 45
Francesco Giovanni 100 Luca 50 Piero 200";


        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);

        while (matcher.find())
        System.out.println(matcher.group());
}
Ottengo in uscita:

Codice:
Anton.Luca
Bianca
Claudio
Ciro
Claudio
Francesco
Francesco
Giovanni
Luca
Piero
L'espressione regolare voleva catturare anche nomi dati nel formato Nome.Nome, ecco perché ho inserito il .

Con una regex simile riesco ad ottenere le distanze a cui si trovano gli amici:

Codice:
String regex = "[0-9]{2,3}";

IL PROBLEMA E' CHE NON RIESCO A VERIFICARE se il file di input rispetta complessivamente il formato dato

Idee?

Il secondo file è simile ma contiene anche un altro dato (affinità) introdotto subito dopo la distanza e separato dal carattere pipe (|). Me ne occuperò dopo..
__________________

Alla povertà mancano molte cose, all'avarizia tutte.
DeltaDirac è offline   Rispondi citando il messaggio o parte di esso
Old 11-07-2011, 09:10   #2
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2794
Ho provato a scrivere una regex ma non so se funziona:
Codice:
(([A-Za-z\.]+\s){2}\d+(\s[A-Za-z\.]+\s\d+)*[\n\r]*)+
Te la spiego a pezzi;
Codice:
([A-Za-z\.]+\s){2}\d+
Questo serve a matchare i primi due nomi più il numero: [A-Za-z\.] matcha le lettere più il punto, con il + ripeti il match, con \s matchi lo spazio e con {2} ripeti il match precedente (quello tra parentesi tonde), con \d matchi i digit, cioè i numeri;
Codice:
(\s[A-Za-z\.]+\s\d+)*
Questo matcha le coppie nome-numero successive, con * il match può avvenire 0 o più volte;
Codice:
[\n\r]*
Per matchare il fine riga (non sapendo se è presente solo \n o anche \r ho usato la classe, con * e non + perché non so se il file termina con un ritorno a capo);
Codice:
(tutto)+
Matcha una o più righe, puoi sostituire il + con un * se il file può anche essere vuoto.

Non avendola testata non sono sicuro che sia corretta, comunque credo che ti serva una cosa del genere.
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 11-07-2011, 18:46   #3
DeltaDirac
Senior Member
 
L'Avatar di DeltaDirac
 
Iscritto dal: Jan 2007
Città: Firenze
Messaggi: 2906
Così come è scritta non riesco a farla funzionare per sintassi gobba (illegal escape caracter, 6 volte) ; duplicando tutti i caratteri \ come segue:

Codice:
"(([A-Za-z\\.]+\\s){2}\\d+(\\s[A-Za-z\\.]+\\s\\d+)*[\n\r]*)+"
ma non riesco a fare la validazione.
__________________

Alla povertà mancano molte cose, all'avarizia tutte.

Ultima modifica di DeltaDirac : 12-07-2011 alle 06:45.
DeltaDirac è offline   Rispondi citando il messaggio o parte di esso
Old 11-07-2011, 19:40   #4
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2794
In tal caso credo che tu debba raddoppiare anche i backslash di n ed r. Comunque non ho capito se ha funzionato
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 12-07-2011, 06:46   #5
DeltaDirac
Senior Member
 
L'Avatar di DeltaDirac
 
Iscritto dal: Jan 2007
Città: Firenze
Messaggi: 2906
Ad es.

Codice:
        String regex = "(([A-Za-z\\.]+\\s){2}\\d+(\\s[A-Za-z\\.]+\\s\\d+)*[\\n\\r]*)+";
        String input = "Anton.Luca Bianca 150 Claudio 14 Ciro 280 Claudio Francesco 45 Francesco Giovanni 100 Luca 50 Piero 200 2 2 2";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);

        while (matcher.find())
        System.out.println(matcher.group());
Dovrebbe fallire perché mancano sostanzialmente tutti i caratteri ( : ) che delimitano i due campi e c'è una ripetizione di numeri alla fine della linea.

Una stringa di input valida sarebbe invece "Franco Luca 10:12 Giovanni 6:3 Matteo 19:199"

Questa stringa contiene anche il secondo problema di cui accennavo all'inizio: vorrei validare ogni linea del file solo se aderisce a quel formato (nome1 nome2 numero1:numero2 nome3 numero4:numero5 ... ).
Invece non riesco proprio ad uscirne :muro
__________________

Alla povertà mancano molte cose, all'avarizia tutte.

Ultima modifica di DeltaDirac : 12-07-2011 alle 06:48.
DeltaDirac è offline   Rispondi citando il messaggio o parte di esso
Old 12-07-2011, 08:27   #6
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2794
Scusa ma mi stai un po' confondendo... in quest'ultimo post hai usato una sintassi diversa da quella del primo post. Cosa devi validare esattamente?
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 12-07-2011, 12:40   #7
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Volevo proporre una soluzione non basata sull'uso delle regex.
Definisco una classe astratta (TextValidator) che rappresenta l'algoritmo generico di validazione di una sorgente di testo; in particolare astrae la semantica di validazione e la semantica di scomposizione in token di una data linea nella sorgente:
Codice:
package stringsplitting.textvalidator;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;

/**
 * Abstract class to perform validation of a text source.
 */
public abstract class TextValidator
{
    /**
     * Line separator in text file/stream
     */
    public static final String NEWLINE = System.getProperty("line.separator");
    
    /**
     * Main algorithm to validate a given text source
     * @param source  a stream of text
     * @return true if the text source is valid
     */
    public boolean isValid(InputStream source) {
        String txt = getText(source);
        if (txt == null) return false;

        int num = 1;
        for (String line : getAllLines(txt)) {
            String[] tokens = getTokens(line, num);
            if (! isValid(tokens, num)) return false;
            num++;
        }

        return true;
    }

    /* utility method to extract all text from the source */
    private String getText(InputStream source) {
        Scanner scan = null;
        try {
            scan = new Scanner(source);
            return scan.useDelimiter("\\z").next();
        } finally {
            if (scan != null) scan.close();
        }
    }

    /* utility method to extract all lines from the text */
    private String[] getAllLines(String txt) {
        StringTokenizer st = new StringTokenizer(txt, NEWLINE);
        List<String> lines = new ArrayList<String>(st.countTokens());
        while (st.hasMoreTokens()) lines.add(st.nextToken());
        final int N = lines.size();
        return lines.toArray(new String[N]);
    }

    /**
     * Implementation-specific semantic for validating a given line
     * @param tokens  the tokens taht form the given line
     * @param number  the number of the line in the text
     * @return true if the given line is valid
     */
    abstract protected boolean isValid(String[] tokens, int number);

    /**
     * Implementation-specific semantic for tokenizing a given line
     * @param line the line to tokenize
     * @param number  the number of the line in the text
     * @return the given line decomposed into an array of tokens
     */
    abstract protected String[] getTokens(String line, int number);
}
Quindi, a seconda del formato, definisco un'implementazione apposita.
Nell'esempio qui sotto, due implemantazioni di TextValidator per due formati che ho scelto traendoli dalle descrizioni dell'utente.
Tra il primo e il secondo formato (quello con i versetti presenti) c'è della logica condivisa il che mi permette di definire il secondo "validatore" come estensione del primo (sovvrascrivendo le operazioni differenti, e aggiungendo quelle mancanti):
Codice:
package stringsplitting.textvalidator;

import java.io.InputStream;

/**
 * Check the format of a given text file.<br>
 */
public class ValidatorExample
{
    public static void main(String[] args) {
        InputStream in = ValidatorExample.class.getResourceAsStream("input2.txt");

        MyTextValidator2 check = new MyTextValidator2();
        if (check.isValid(in))
            System.out.println("File is valid.");
        else
            System.out.println("File is malformed.");
    }

    /**
     * Custom implementation of a TextValidator
     * format is:<br>
     * nameOrDot [name value]
     * <p>
     * nameOrDot -> letters.letters | letters<br>
     * name -> letters<br>
     * value -> integer<br>
     */
    static class MyTextValidator1 extends TextValidator
    {
        @Override
        protected boolean isValid(String[] tokens, int number) {
            String tok = tokens[0];
            if (! isNameOrDot(tok)) return false;

            if (tokens.length > 1) {
                if (tokens.length % 2 == 0) return false;
                for (int i=1; i<tokens.length-1; i+=2) {
                    String s1 = tokens[i];
                    if (! isName(s1)) return false;
                    String s2 = tokens[i+1];
                    if (! isValue(s2)) return false;
                }
            }

            return true;
        }

        @Override
        protected String[] getTokens(String line, int number) {
            return line.split(" ");
        }

        // @impl
        protected boolean isName(String str) {
            for (char c : str.toCharArray())
                if (! Character.isLetter(c)) return false;
            return true;
        }

        // @impl
        protected boolean isNameOrDot(String str) {
            for (char c : str.toCharArray())
                if ((! Character.isLetter(c)) && c != '.') return false;
            return true;
        }

        // @impl
        protected boolean isValue(String str) {
            try {
                Integer.parseInt(str);
                return true;
            } catch (NumberFormatException e) {
                return false;
            }
        }
    }

    /**
     * Custom implementation of another TextValidator
     * format is:<br>
     * nameOrDot [name verse]
     * <p>
     * nameOrDot -> letters.letters | letters<br>
     * name -> letters<br>
     * verse -> integer:integer
     * <p>
     * Reuse functionality already implemented in MyTextValidator1
     */
    static class MyTextValidator2 extends MyTextValidator1
    {
        @Override
        protected boolean isValid(String[] tokens, int number) {
            if (tokens.length < 3) return false;
            if (tokens.length % 2 == 0) return false;

            String tok = tokens[0];
            if (! isNameOrDot(tok)) return false;
            
            for (int i=1; i<tokens.length-1; i+=2) {
                String s1 = tokens[i];
                if (! isName(s1)) return false;
                String s2 = tokens[i+1];
                if (! isVerse(s2)) return false;
            }

            return true;
        }

        // @impl
        private boolean isVerse(String str) {
            int index = str.indexOf(':');
            if (index == -1) return false;

            String s1 = str.substring(0, index);
            if (! isValue(s1)) return false;

            String s2 = str.substring(index+1);
            if (! isValue(s2)) return false;

            return true;
        }
    }
}
Il primo validatore l'ho provato con questo input:
Codice:
Anton.Luca Bianca 150 Claudio 14 Ciro 280
Claudio Francesco 45
Francesco Giovanni 100 Luca 50 Piero 200
e il secondo con questo:
Codice:
Franco Luca 10:12 Giovanni 6:3
Carlo Luca 10:12
Luisa Giovanni 6:3 Matteo 19:199
Antonio.Rossi Matteo 19:199
Mattia Luca 10:12 Giovanni 6:3 Matteo 19:199
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Tra audio e AI: la ricetta di Qualcomm per l'agentic AI Tra audio e AI: la ricetta di Qualcomm per l'age...
Qualcomm annuncia la nuova generazione di SoC Snapdragon 8 Elite Gen 6 Qualcomm annuncia la nuova generazione di SoC Sn...
realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole! realme 16 Pro Harry Potter Edition: il nuovo mid...
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce Recensione REDMI Note 17 Pro: il midrange con ba...
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema Insta360 Luna Ultra: la potenza del sensore da 1...
Auto elettriche UE al 21,7%: sorpasso si...
GPT-6 Astra ha decifrato un messaggio na...
Registra a 7.471 fps e costa quanto un'u...
Microsoft riporta in vita Surface Mouse ...
OpenAI porta le funzioni agentiche vocal...
La Cina indaga su DeepSeek e Moonshot: a...
Sono 68.450 gli oggetti oltre i 10 centi...
950 agenti, 210 milioni di token e 21 or...
Dopo quasi 40 anni l'Italia riapre al nu...
Apple Intelligence su macOS 27 potrebbe ...
NVIDIA prepara la grafica del futuro con...
YouTube annuncia nuovi strumenti per per...
Phishing a nome ACI sul bollo auto: una ...
3 mini-PC ASUS per usare l'intelligenza ...
YouTube punta sempre di più sull'...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 13:39.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v