Java - Espressioni Regolari

Benvenuti, aspiranti programmatori Java! Oggi, ci immergeremo nel fascinante mondo delle Espressioni Regolari (Regex) in Java. Non preoccupatevi se siete nuovi alla programmazione; vi guiderò attraverso questo viaggio passo per passo, proprio come ho fatto per innumerevoli studenti durante gli anni della mia docenza. Quindi, prenda una tazza di caffè e iniziamo insieme questa avventura entusiasmante!

Java - Regular Expressions

Cos'sono le Espressioni Regolari?

Prima di saltare nell'implementazione specifica di Java, capiamo cosa sono le Espressioni Regolari. Immagina di essere un detective che cerca un pattern specifico in un mare di testo. Esattamente questo fa Regex – è uno strumento potente per la corrispondenza e la manipolazione delle stringhe.

Classi di Espressioni Regolari di Java

Java fornisce un package chiamato java.util.regex che contiene diverse classi per lavorare con le espressioni regolari. Le tre classi principali su cui ci concentreremo sono:

  1. Pattern
  2. Matcher
  3. PatternSyntaxException

Esploriamo ciascuna di queste in dettaglio.

Classe Pattern

La classe Pattern rappresenta una rappresentazione compilata di un'espressione regolare. Pensatela come il progetto per il tuo lavoro di corrispondenza detective.

import java.util.regex.Pattern;

public class EsempioPattern {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("Ciao");
System.out.println("Pattern creato: " + pattern);
}
}

In questo esempio, stiamo creando un pattern semplice che corrisponde alla parola "Ciao". Il metodo compile() prende l'espressione regolare come stringa e restituisce un oggetto Pattern.

Classe Matcher

La classe Matcher è dove avviene la magia reale. Esegue operazioni di corrispondenza su una sequenza di caratteri in base a un Pattern.

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class EsempioMatcher {
public static void main(String[] args) {
String text = "Ciao, Mondo! Ciao, Java!";
Pattern pattern = Pattern.compile("Ciao");
Matcher matcher = pattern.matcher(text);

while (matcher.find()) {
System.out.println("Trovata corrispondenza all'indice: " + matcher.start());
}
}
}

Questo codice cerca il pattern "Ciao" nel testo dato e stampa l'indice di inizio di ogni corrispondenza. È come se il nostro detective trovasse tutte le occorrenze di una pista in un documento!

Sintassi delle Espressioni Regolari

Ora, vediamo una sintassi di base per creare pattern più complessi. Ecco una tabella dei metacaratteri comunemente utilizzati:

Metacarattere Descrizione
. Corrisponde a qualsiasi carattere singolo
^ Corrisponde all'inizio della riga
$ Corrisponde alla fine della riga
* Corrisponde a zero o più occorrenze
+ Corrisponde a una o più occorrenze
? Corrisponde a zero o una occorrenza
\d Corrisponde a un cifra
\s Corrisponde a un carattere di spaziatura
\w Corrisponde a un carattere alfanumerico (lettera, cifra o underscore)

Vediamo alcuni di questi in azione:

public class EsempioSintassiRegex {
public static void main(String[] args) {
String text = "Il volatile brown fox salta sopra il pigro cane";

// Corrisponde a parole che iniziano con 'q'
Pattern pattern1 = Pattern.compile("\\bq\\w+");
Matcher matcher1 = pattern1.matcher(text);
if (matcher1.find()) {
System.out.println("Parola che inizia con 'q': " + matcher1.group());
}

// Corrisponde a parole che terminano con 'g'
Pattern pattern2 = Pattern.compile("\\w+g\\b");
Matcher matcher2 = pattern2.matcher(text);
if (matcher2.find()) {
System.out.println("Parola che termina con 'g': " + matcher2.group());
}
}
}

In questo esempio, stiamo utilizzando \b per corrispondere ai confini delle parole, \w+ per corrispondere a uno o più caratteri alfanumerici, e combinandoli con 'q' e 'g' per trovare parole che iniziano con 'q' e terminano con 'g' rispettivamente.

Gruppi di Cattura nelle Espressioni Regolari

I gruppi di cattura consentono di trattare più caratteri come una singola unità. Vengono creati mettendo i caratteri da raggruppare tra parentesi.

public class EsempioGruppoCattura {
public static void main(String[] args) {
String text = "John Doe ([email protected])";
Pattern pattern = Pattern.compile("(\\w+)\\s(\\w+)\\s\\((\\w+@\\w+\\.\\w+)\\)");
Matcher matcher = pattern.matcher(text);

if (matcher.find()) {
System.out.println("Nome: " + matcher.group(1));
System.out.println("Cognome: " + matcher.group(2));
System.out.println("Email: " + matcher.group(3));
}
}
}

In questo esempio, stiamo estraendo il nome, il cognome e l'indirizzo email di una persona da una stringa. Le parentesi nel pattern creano gruppi di cattura, che possiamo accedere utilizzando matcher.group(n).

Metodi della Classe Matcher

La classe Matcher fornisce diversi metodi utili. Ecco alcuni dei più comunemente utilizzati:

Metodo Descrizione
find() Trova la prossima corrispondenza per il pattern
group() Restituisce la sottostringa corrispondente
start() Restituisce l'indice di inizio della corrispondenza
end() Restituisce l'indice di fine della corrispondenza
matches() Controlla se l'intera stringa corrisponde al pattern

Vediamo questi metodi in azione:

public class EsempioMetodiMatcher {
public static void main(String[] args) {
String text = "La pioggia in Spagna cade principalmente sul piano";
Pattern pattern = Pattern.compile("\\b\\w+ain\\b");
Matcher matcher = pattern.matcher(text);

while (matcher.find()) {
System.out.println("Trovato: " + matcher.group());
System.out.println("Indice di inizio: " + matcher.start());
System.out.println("Indice di fine: " + matcher.end());
}
}
}

Questo codice trova tutte le parole che terminano con "ain" e stampa ogni corrispondenza insieme ai suoi indici di inizio e fine.

Metodi di Sostituzione delle Espressioni Regolari

Le espressioni regolari non sono solo per trovare pattern; sono anche grandi per sostituire testo. La classe Matcher fornisce metodi per questo scopo:

public class EsempioSostituzione {
public static void main(String[] args) {
String text = "Il volatile brown fox salta sopra il pigro cane";
Pattern pattern = Pattern.compile("fox|cane");
Matcher matcher = pattern.matcher(text);

String result = matcher.replaceAll("animale");
System.out.println("Dopo la sostituzione: " + result);
}
}

In questo esempio, sostituiamo sia "fox" che "cane" con "animale". Il metodo replaceAll() fa tutto il lavoro pesante per noi!

Classe PatternSyntaxException

A volte, possiamo fare errori mentre scriviamo le nostre espressioni regolari. Ecco dove entra in gioco la classe PatternSyntaxException. Viene lanciata per indicare un errore di sintassi in un pattern di espressione regolare.

public class EsempioPatternSyntaxException {
public static void main(String[] args) {
try {
Pattern.compile("[");  // Regex invalido
} catch (PatternSyntaxException e) {
System.out.println("Eccezione di sintassi del pattern: " + e.getMessage());
System.out.println("Indice dell'errore: " + e.getIndex());
}
}
}

Questo codice utilizza deliberatamente un regex invalido per dimostrare come funziona PatternSyntaxException. È come avere un correttore automatico integrato per le vostre espressioni regolari!

Eccoci qua, ragazzi! Abbiamo viaggiato attraverso la terra delle Espressioni Regolari di Java, dai pattern di base ai sostituti complessi. Ricorda, come ogni strumento potente, regex diventa più utile man mano che si pratica. Quindi, non esitare a sperimentare e creare i tuoi pattern. Chi sa? Potresti diventare il Sherlock Holmes della corrispondenza dei pattern!

Buon coding, e possa le tue stringhe sempre corrispondere alle tue aspettative!

Credits: Image by storyset