Java regexp

di Paolovox il
10 risposte
Mi sono appena addentrato nel mondo delle espressioni regolari.
Ho una stringa del tipo:

String s = "3.1415 42 23 3.16 9.18 ";
Come faccio a matchare un qualsiasi carattere alfabetico all'interno della stringa in una qualsiasi posizione?

Ho provato con:

if (s.matches("[a-zA-Z]")) throw new IllegalArgumentException();

10 Risposte

  • La funzione matches ritorna true solo se tutta la stringa corrisponde alla regex.. prova con
    [A-Za-z]+
  • Già provato ma niente. Non penso vadano fatti tanti casi di pattern quante siano le possibilità di beccare una lettera nella stringa. Altrimenti mi converrebbe iterare sui caratteri della stringa e controllare:
    
    if (Character.isLetter(stringa.charAt(index)) throw new IllegalArgumentException();
    
    però lo voglio risolvere con le espressioni regolari
  • Wow ci son riuscito dopo un lungo bruteforce
    
    if (stringa.matches("\\s*.*[a-z].*\\s*")) throw new IllegalArgumentException();
    
    se ci stanno zero o più spazi prima di zero o più token, matcho il char, e se dopo ci stanno zero o più token seguiti da zero o più spazi, il match si è verificato.

    Non so se è comprensibile però funziona. Grazie
  • Ciao, se vuoi cercare delle cose all'interno di una stringa puoi usare la classe Matcher, in particolare il metodo find():
    
    String s = "3.141a5 42 23 wasd 3.1lol6 9.18 ";
    Pattern pattern = Pattern.compile("[a-zA-Z]+");
    Matcher matcher = pattern.matcher(s);
    while (matcher.find()) {
       System.out.println(s.substring(matcher.start(), matcher.end()));
    }
    
    In questo modo ti verranno stampate tutte e sole le porzioni di s che contengono almeno una lettera, ovvero:
    a
    wasd
    lol
    .

    Se invece ti interessa prendere il singolo carattere puoi modificare la sola regex, oppure semplificare un pochino il codice:
    
    String s = "3.141a5 42 23 wasd 3.1lol6 9.18 ";
    Pattern pattern = Pattern.compile("[a-zA-Z]");
    Matcher matcher = pattern.matcher(s);
    while (matcher.find()) {
        System.out.println(s.charAt(matcher.start()));
    }
    
  • Grazie mille, molto utile.
    Le funzioni per il match di pattern come sono implementati alla base dei linguaggi C,BASH,JAVA, ecc...?
  • Non so come siano implementate in java, ma i linguaggi regolari equivalgono ad automi a stati finiti, quindi penso che si sfrutti qualcosa di simile
  • Sarebbe interessante saperlo per capire quanto costo computazionale esercita un match a differenza di iterare su una stringa.
  • Se vuoi saperlo ad un livello di dettaglio così elevato puoi andare a vedere il codice di Matcher.java (su google dovresti trovare un po' di materiale)..ho paura che non sia semplicissimo però


    Sent from my iPhone using Tapatalk
  • Ci sono specifici teoremi che dimostrano che un'espressione regolare puo' essere convertita in automa a stati finiti deterministico il quale ha fondamentalmente un comportamento lineare. Cioe' non ci sono ritentativi di matching (faccio un primo tentativo, fallisce, ritento, ...).
    Se l'implementazione e' ben fatta (e sicuramente lo e'), molto probabilmente sara' efficiente almeno quanto la migliore implementazione fatta mano. E' ovvio che ci possono essere dei casi (semplici) in cui l'implementazione a mano e' migliore, ma dove si ricupera in efficienza, si perde in flessibilita'.
    Quindi bisogna valutare se la migliore efficienza migliora le performance dell'applicazione del 50% (vale la pena), 10% (piu' no che si), 1% o 0.0000001% (non ne vale la pena )
  • Sforzo di immaginazione spero non inutile.
    Nel momento in cui costruiamo una regex viene costruita la struttura dell'automa. La stringa viene data in input al nostro automa creato e facendola scorrere se arriva ad uno stato finale il nostro pattern fa match, altrimenti no.
    Grazie comunque ancora ce n'è tanto di studio da fare.
Devi accedere o registrarti per scrivere nel forum
10 risposte