Ingegneria · 23 settembre 2026

Testare le espressioni regolari: come provare e fare il debug di un regex prima della produzione

Un regex che funziona con l’esempio in testa può fallire su dati reali. Un workflow pratico per testare i pattern nel browser: flag, gruppi di cattura, backtracking catastrofico e pattern leggibili.

La maggior parte dei bug nelle espressioni regolari non sono errori di sintassi. Un pattern può essere perfettamente valido ed essere comunque sbagliato: cattura troppo, cattura troppo poco o — peggio — blocca la pagina quando incontra una stringa ostile. Tra un pattern che funziona con gli esempi in testa e uno che funziona con dati reali ci sono i test.

Questo articolo descrive un workflow pratico per scrivere, testare e fare il debug di espressioni regolari nel browser, più i fallimenti che mordono più spesso.

Testa con dati reali, non con esempi di prova

Le stringhe di prova adulano un pattern. Un input reale contiene a capo dimenticati, spazi finali, emoji, valori vuoti e quaranta kilobyte di markup copiato.

  • Incolla il campione reale peggiore che hai — idealmente quello che ha già rotto qualcosa.
  • Includi la stringa vuota, un singolo carattere e una riga molto lunga.
  • Includi testo non ASCII se l’input può contenerlo: Ü, 日本語, 🙂.
  • Conta i match, non solo il primo. I quantificatori con errore di uno e le sovrapposizioni golose compaiono solo qui.

Testare con evidenziazione in tempo reale rende l’operazione economica: ogni posizione di match si aggiorna mentre modifichi il pattern, invece di riemergere tre giorni dopo in un file di log.

I flag cambiano il significato di un pattern

La stessa espressione si comporta diversamente a seconda dei flag con cui viene eseguita:

Flag Effetto Sorpresa tipica
i ignora maiuscole e minuscole cattura anche identificatori che volevi distinguere
g globale — trova tutti i match in JavaScript, test() e exec() mantengono stato tra le chiamate
m multilinea — ^ e $ per riga ^ non significa più «inizio stringa»
s il punto cattura anche i ritorni a capo .* inizia a superare i confini di riga
u modalità Unicode necessario per gli escape a punto di codice

Il flag g di JavaScript merita una menzione: con esso regex.test() incrementa lastIndex, per cui chiamate ripetute sullo stesso oggetto restituiscono risposte diverse. È la fonte classica del bug «funziona una volta, fallisce al secondo tentativo».

Gruppi di cattura e gruppi con nome

I gruppi estraggono dati, ma costano anche memoria e rendono il pattern più difficile da leggere.

// i gruppi con nome sopravvivono al riordinamento, quelli numerati no
const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const m = "2026-09-22".match(re);
m.groups.year;  // "2026"
m.groups.month; // "09"

Preferisci i gruppi con nome a quelli numerati, così riordinare il pattern non sposta silenziosamente i tuoi riferimenti. Se hai bisogno di parentesi solo per raggruppare e non per catturare, usa un gruppo non catturante: (?:...).

Backtracking catastrofico

Quantificatori annidati come (a+)+$ o (\s*)* possono mandare un motore in tempo esponenziale su stringhe che quasi corrispondono. Il pattern è istantaneo su input amichevoli e si blocca su un input ostile — ed è esattamente quello che invia un attaccante.

  • Evita quantificatori su gruppi che ne contengono già.
  • Ancora dove puoi. ^ e $ consentono al motore di rifiutare presto.
  • Sottoponi a una lunga stringa quasi-corrispondente. Se il tempo di match cresce con ogni carattere aggiunto, il pattern non è sicuro.
  • Valuta un motore a tempo lineare (stile RE2) per input non affidabili lato server.

Mantieni i pattern leggibili

  • Dai un nome al pattern nel codice — const ISO_DATE = /.../ batte un letterale anonimo ripetuto in sei file.
  • Usa la modalità a spazi liberi (x) se il motore la supporta, per aggiungere commenti e spazi dentro il pattern.
  • Sii esplicito sulle cifre. [0-9] significa cifre ASCII; \d corrisponde anche ad altri sistemi di scrittura in modalità Unicode.
  • Lascia due esempi con il pattern: uno che deve corrispondere e uno che non deve.

Un workflow pratico

Passo Cosa controlli
1. Scrivi il pattern più piccolo che corrisponde a un campione reale l’evidenziazione cade dove ti aspetti
2. Aggiungi campioni negativi nessun match sugli input che devono fallire
3. Attiva i flag deliberatamente ogni flag c’è per un motivo
4. Sottoponi il pattern a input lunghi e ostili il match appare istantaneamente
5. Converti in codice con gruppi con nome nessun riferimento posizionale residuo

Provalo

Apri un tester di regex, incolla il tuo pattern e un campione reale e osserva ogni match evidenziarsi mentre scrivi. Poiché il test gira nel tuo browser, il testo che stai validando non lascia mai il tuo dispositivo — e conta non appena il campione contiene un token, una chiave o dati di clienti.