Le espressioni regolari hanno la reputazione di sembrare rumore casuale. Un pattern come ^[\w.-]+@[\w-]+\.\w{2,}$ può dare l'impressione che un gatto abbia camminato sulla tastiera. Ma dietro la sintassi criptica si nasconde un'idea straordinariamente elegante: un linguaggio conciso per descrivere pattern nel testo.
Che tu stia validando input di moduli, cercando nei file di log, pulendo dati o facendo cerca-e-sostituisci in un codebase, le regex sono uno degli strumenti più versatili nel kit di uno sviluppatore. E non hai bisogno di memorizzare ogni oscura funzionalità per trarne un valore reale. Una manciata di mattoni copre la stragrande maggioranza dei casi d'uso pratici.
Cosa fanno le regex in pratica
Un'espressione regolare (regex o regexp) è un pattern che descrive un insieme di stringhe. Lo fornisci a un motore di ricerca — nel tuo linguaggio di programmazione, editor di testo o strumento da riga di comando — e trova ogni stringa corrispondente.
Pensala come una ricerca potenziata:
- Ricerca normale: trova la parola esatta "error"
- Ricerca regex: trova qualsiasi cosa che assomigli a un indirizzo IP, una data, un indirizzo email o qualsiasi struttura che puoi descrivere
Le regex furono inventate dal matematico Stephen Kleene nel 1956 ed entrarono nell'informatica attraverso gli editor di testo Unix negli anni '60. Oggi sono supportate praticamente in ogni linguaggio di programmazione e editor di testo.
I mattoni fondamentali
Caratteri letterali
La regex più semplice è testo semplice. Il pattern hello corrisponde alla stringa "hello" ovunque appaia. Niente di complicato.
Il punto (.) — qualsiasi carattere
Un punto corrisponde a qualsiasi singolo carattere eccetto un a-capo.
h.tcorrisponde a "hat", "hit", "hot", "h3t" e persino "h t"
Classi di caratteri ([])
Le parentesi quadre definiscono un insieme di caratteri consentiti in una posizione.
[aeiou]— qualsiasi vocale[0-9]— qualsiasi cifra[A-Za-z]— qualsiasi lettera[^0-9]— qualsiasi carattere che NON è una cifra (il^dentro le parentesi significa "non")
Classi abbreviate
| Abbreviazione | Significato | Equivalente |
|---|---|---|
\d |
Qualsiasi cifra | [0-9] |
\w |
Carattere di parola | [A-Za-z0-9_] |
\s |
Spazio bianco | [ \t\n\r] |
\D |
Non una cifra | [^0-9] |
\W |
Non un carattere di parola | [^A-Za-z0-9_] |
\S |
Non uno spazio bianco | [^ \t\n\r] |
Quantificatori — quante volte
I quantificatori controllano quante volte l'elemento precedente deve apparire.
| Simbolo | Significato | Esempio | Corrisponde a |
|---|---|---|---|
* |
Zero o più | ab*c |
"ac", "abc", "abbc" |
+ |
Uno o più | ab+c |
"abc", "abbc" (non "ac") |
? |
Zero o uno | colou?r |
"color" e "colour" |
{3} |
Esattamente 3 | \d{3} |
"123", "456" |
{2,4} |
Tra 2 e 4 | \d{2,4} |
"12", "123", "1234" |
Ancore — posizione
^— inizio della stringa (o della riga, con il flagm)$— fine della stringa (o della riga)\b— confine di parola
Il pattern ^\d{4}$ corrisponde a una stringa che è esattamente quattro cifre, come "2026", ma non "abc2026" o "2026xyz".
Gruppi e alternanza
(abc)— cattura "abc" come gruppoa|b— corrisponde a "a" o "b"(cat|dog)— corrisponde a "cat" o "dog"
I gruppi permettono anche di applicare quantificatori a sequenze: (ha)+ corrisponde a "ha", "haha", "hahaha".
Pattern pratici comuni
Validare un'email (base)
^[\w.-]+@[\w-]+\.\w{2,}$
Corrisponde a user@example.com, first.last@company.co.uk (parzialmente), e rifiuta stringhe senza @ o dominio.
Importante: Validare perfettamente gli indirizzi email con le regex è notoriamente difficile — la specifica completa RFC 5322 è estremamente complessa. Per i sistemi in produzione, usa una regex di base per il controllo del formato e poi verifica l'indirizzo inviando un'email di conferma.
Trovare un numero di telefono
\+?\d{1,3}[-.\s]?\(?\d{1,4}\)?[-.\s]?\d{3,4}[-.\s]?\d{3,4}
Gestisce formati come +1 555 123 4567, 555-123-4567 e (555) 123-4567.
Trovare un URL
https?://[\w.-]+(/[\w./?&=-]*)?
Corrisponde a https://example.com, http://example.com/path?q=hello.
Trovare una data (YYYY-MM-DD)
\d{4}-\d{2}-\d{2}
Corrisponde a 2026-03-29, 1999-12-31. Nota: verifica solo il formato, non la validità — corrisponderebbe anche a 9999-99-99.
Flag che cambiano il comportamento
La maggior parte dei motori regex supporta flag che modificano l'applicazione del pattern:
| Flag | Nome | Effetto |
|---|---|---|
g |
Globale | Trova tutte le corrispondenze, non solo la prima |
i |
Senza distinzione maiuscole/minuscole | hello corrisponde a "Hello", "HELLO", ecc. |
m |
Multilinea | ^ e $ corrispondono a inizio/fine di ogni riga |
s |
Dotall | . corrisponde anche ai caratteri di a-capo |
In JavaScript, i flag vengono aggiunti dopo lo slash di chiusura: /hello/gi. In Python, vengono passati come argomenti: re.findall(r"hello", text, re.IGNORECASE).
Quando le regex sono eccessive
Le regex sono potenti, ma non sono sempre lo strumento giusto:
- Parsing di HTML o XML. Usa un parser DOM appropriato. Le regex non possono gestire in modo affidabile i tag annidati.
- Parsing di JSON. Usa
JSON.parse()o equivalente. Le regex falliranno sui casi limite. - Validazione complessa. Se il tuo pattern si estende su più righe e richiede cinque minuti per essere letto, considera di scrivere codice di validazione procedurale.
- Operazioni semplici sulle stringhe. Se hai solo bisogno di
startsWith(),includes()osplit(), i metodi stringa semplici sono più chiari e veloci.
Insidie comuni
- Dimenticare di eseguire l'escape dei caratteri speciali. Il punto
.corrisponde a qualsiasi carattere. Per corrispondere a un punto letterale, usa\.. Lo stesso vale per(,),[,],+,*,?,{,},^,$,|e\. - Matching greedy vs. lazy. Per impostazione predefinita,
.*è greedy — corrisponde al massimo possibile. Aggiungi?per renderlo lazy:.*?corrisponde al minimo possibile. Questo è importante quando si estrae contenuto tra delimitatori. - Backtracking catastrofico. Quantificatori annidati come
(a+)+possono causare al motore di provare un numero esponenziale di percorsi su certi input, bloccando il tuo programma. Evita ripetizioni annidate su pattern sovrapposti. - Dimenticare le ancore. Senza
^e$, il tuo pattern corrisponde a sottostringhe.\d{3}corrisponde a "123" dentro "abc12345". Usa^\d{3}$se hai bisogno di una corrispondenza esatta.
Per approfondire
Il modo migliore per imparare le regex è sperimentare. Scrivi un pattern, incolla del testo di prova e osserva cosa viene evidenziato. Modifica e itera finché non capisci come funziona ogni pezzo.
- Come testare i pattern regex — tutorial interattivo con esempi
- Tester regex — incolla il tuo pattern e i dati di test, visualizza le corrispondenze evidenziate in tempo reale
