Domande Frequenti (FAQ) sulle Regex

Guida tecnica essenziale su sintassi, sicurezza ReDoS, compatibilità tra linguaggi e buone pratiche di ingegneria software.

Un’espressione regolare è una sequenza formale di caratteri che definisce un modello di ricerca (search pattern). Viene impiegata per verificare se una stringa rispetta un dato formato (validazione), per individuare o estrarre sottostringhe specifiche (parsing/estrazione) o per sostituire porzioni di testo secondo regole strutturate.

Una regex controlla esclusivamente la correttezza formale della sequenza di caratteri. Non può verificare l’esistenza reale o la semantica del dato: ad esempio, una regex per email conferma la presenza di `@` e dominio valido ma non che la casella esista (serve un’email di verifica); una regex per Codice Fiscale verifica i 16 caratteri alfanumerici ma non calcola il check digit o l’omocodia; una regex per carta di credito controlla lunghezza e prefisso circuito ma non esegue l’algoritmo di Luhn né contatta il gateway di pagamento.

Il ReDoS (Regular Expression Denial of Service) è una vulnerabilità che si verifica quando un motore di regex basato su NFA (come PCRE o JavaScript) tenta di valutare un pattern contenente quantificatori annidati o sovrapposti su una stringa non corrispondente, generando un numero esponenziale di combinazioni di backtracking. Per difendersi: evitare costrutti ambigui come `(a+)+`, imporre limiti massimi alla lunghezza dell’input utente, utilizzare motori lineari DFA (come RE2 in Go o Rust) oppure impostare timeout rigidi di esecuzione (come il timeout di 500 ms nel Web Worker di questo tester).

No. Pur condividendo i simboli base, esistono differenze cruciali tra dialetti: PCRE (usato da PHP) supporta ricorsione avanzata, subroutine e lookbehind a lunghezza variabile; JavaScript ha introdotto i gruppi nominati e il flag `s` (dotAll) solo in ES2018; Python usa moduli con sintassi raw string `r"..."`; Go utilizza il motore RE2 privo di backtracking ma non supporta lookaround o backreference. Verificare sempre il motore target prima di distribuire il pattern.

HTML e XML sono linguaggi a grammatica context-free (CFG) con alberi gerarchici arbitrariamente annidati, mentre le espressioni regolari classiche descrivono linguaggi regolari. Sebbene le regex siano ottime per estrarre attributi isolati (es. `href` o `src`), il parsing di documenti completi rischia di fallire su commenti, blocchi script, tag annidati e attributi non standard. In tali casi è preferibile usare parser DOM specializzati (es. `DOMDocument` in PHP o `cheerio`/`jsdom` in JS).

I gruppi nominati consentono di assegnare un nome leggibile a un gruppo di cattura anziché fare affidamento sul solo indice numerico. La sintassi è `(?<nome>pattern)` (oppure `(?P<nome>pattern)` in Python). I linguaggi moderni restituiscono un dizionario/oggetto (es. `matches.groups.nome` in JavaScript o `$matches['nome']` in PHP), rendendo il codice molto più leggibile e resiliente a modifiche future del pattern.

I flag (modificatori) alterano il comportamento del motore di matching: `g` (global) trova tutte le occorrenze nel testo; `i` (case insensitive) ignora la differenza tra maiuscole e minuscole; `m` (multiline) fa sì che `^` e `$` corrispondano all’inizio e fine di ogni riga anziché dell’intero testo; `s` (dotAll) fa corrispondere il carattere `.` anche ai caratteri di nuova riga (`\n`); `u` (unicode) abilita il supporto completo ai code point UTF-8.

Creare una suite di test comprendente sia casi positivi (happy path) che casi limite negativi (falsi positivi noti, stringhe con caratteri speciali, input molto lunghi, whitespace anomali). Sul sito OCEWeb Regex ogni scheda include esempi validi e non validi già collaudati con asserzioni automatizzate al 100%.