Regex Cheat Sheet: Guida Completa alle Espressioni Regolari

Padroneggia le espressioni regolari con questa guida completa. Impara pattern, sintassi, implementazioni specifiche per linguaggio (Python, JavaScript, PHP, C#, Java, Go, Ruby), trasformazioni trova/sostituisci in VS Code e oltre 200 esempi pratici. La risorsa definitiva sulle regex per principianti ed esperti.

G
GUi Softworks
60 min di lettura

Cos'è una Regex?

Le espressioni regolari (regex o regexp) sono sequenze di caratteri che definiscono pattern di ricerca. Sono uno degli strumenti più potenti per l'elaborazione di testi, il riconoscimento di pattern e l'estrazione di dati.

Perché Usare le Espressioni Regolari?

Le regex sono essenziali per:

  • Validazione di form (email, numeri di telefono, password)
  • Estrazione di dati (parsing di log, scraping di pagine web)
  • Elaborazione di testi (trova e sostituisci, formattazione)
  • Refactoring del codice (rinominare variabili, aggiornare sintassi)
  • Sanitizzazione input (sicurezza, prevenzione attacchi injection)

Come Leggere Questa Cheat Sheet

Questa guida è organizzata in sezioni progressive:

  1. Fondamenti - Sintassi e pattern di base
  2. Funzionalità Avanzate - Lookaround, gruppi nominati, Unicode
  3. Specifico per Linguaggio - Esempi in Python, JavaScript, PHP, C#, Java, Go, Ruby
  4. Regex in VS Code - Trasformazioni trova/sostituisci con oltre 20 esempi
  5. Pattern Comuni - Pattern copia-incolla per email, URL, date, ecc.
  6. Casi d'Uso Pratici - Applicazioni del mondo reale
  7. Risoluzione Problemi - Errori comuni e consigli sulle prestazioni

Ogni sezione include:

  • Spiegazioni chiare
  • Esempi visivi
  • Snippet di codice che puoi copiare
  • Suggerimenti professionali e insidie

Caratteri Letterali

La regex più semplice è una sequenza di caratteri letterali:

abc

Corrisponde a: "abc" in "La sequenza abc"

Sensibilità alle Maiuscole

Per impostazione predefinita, le regex sono sensibili alle maiuscole:

  • Ciao corrisponde a "Ciao" ma NON a "ciao"
  • Usa il flag i per corrispondenza insensibile alle maiuscole: /ciao/i

Caratteri Speciali (Metacaratteri)

Questi 12 caratteri hanno significato speciale nelle regex e devono essere escapati con \ per corrispondere letteralmente:

. ^ $ * + ? { } [ ] \ | ( )

Esempi:

  • \. corrisponde a un punto letterale
  • \$ corrisponde a un segno di euro
  • \( corrisponde a una parentesi letterale
Carattere Escape Esempio Corrisponde
. (punto) \. 3\.14 "3.14"
$ (dollaro) \$ \$100 "$100"
* (asterisco) \* a\*b "a*b"

Classi di Caratteri

Classi di Caratteri Predefinite

Pattern Descrizione Equivalente Esempio Corrisponde
\d Qualsiasi cifra [0-9] \d\d "42"
\D Qualsiasi non-cifra [^0-9] \D+ "abc"
\w Carattere word [a-zA-Z0-9_] \w+ "ciao_123"
\W Carattere non-word [^a-zA-Z0-9_] \W "@", "#"
\s Spazio bianco [ \t\n\r\f\v] \s+ " " (spazi)
\S Non-spazio [^ \t\n\r\f\v] \S+ "ciao"
. Qualsiasi carattere eccetto newline - a.c "abc", "a1c"

Suggerimento Pro: \w NON include lettere Unicode per impostazione predefinita. Usa \p{L} per supporto Unicode (JavaScript/Python).

Classi di Caratteri Personalizzate

Pattern Descrizione Esempio Corrisponde
[abc] Corrisponde a qualsiasi di a, b, o c [aeiou] Vocali: "a", "e", "i", "o", "u"
[^abc] Corrisponde a qualsiasi tranne a, b, o c [^0-9] Non-cifre
[a-z] Intervallo: lettere minuscole [a-z]+ "ciao"
[A-Z] Intervallo: lettere maiuscole [A-Z]+ "CIAO"
[0-9] Intervallo: cifre [0-9]{4} "2025"
[a-zA-Z] Combinato: tutte le lettere [a-zA-Z0-9] Alfanumerico

Esempi:

[aeiou]       → Corrisponde a qualsiasi vocale
[^aeiou]      → Corrisponde a qualsiasi consonante (non vocale)
[a-z0-9]      → Corrisponde a lettere minuscole e cifre
[a-zA-Z0-9_]  → Uguale a \w (caratteri word)

Quantificatori

I quantificatori specificano quante volte un pattern deve corrispondere.

Quantificatori Base

Pattern Descrizione Esempio Corrisponde
* 0 o più ab*c "ac", "abc", "abbc", "abbbc"
+ 1 o più ab+c "abc", "abbc" (NON "ac")
? 0 o 1 (opzionale) colou?r "color", "colour"
{n} Esattamente n volte \d{4} "2025" (esattamente 4 cifre)
{n,} n o più volte \d{2,} "42", "123", "9999"
{n,m} Tra n e m volte \d{2,4} "42", "123", "2025"

Quantificatori Greedy vs. Lazy

Greedy (predefinito): Corrisponde al massimo possibile

<.*>      → Corrisponde: "<div>Ciao</div>" (intera stringa)

Lazy (non-greedy): Corrisponde al minimo possibile (aggiungi ? dopo il quantificatore)

<.*?>     → Corrisponde: "<div>" e "</div>" separatamente
Greedy Lazy Descrizione
* *? 0 o più (lazy)
+ +? 1 o più (lazy)
? ?? 0 o 1 (lazy)
{n,m} {n,m}? Tra n e m (lazy)

Esempio:

Testo: "Ciao" e "Mondo"

  • ".*" corrisponde: "Ciao" e "Mondo" (greedy)
  • ".*?" corrisponde: "Ciao" e "Mondo" separatamente (lazy)

Ancoraggi e Confini

Gli ancoraggi corrispondono a posizioni, non caratteri.

Pattern Descrizione Esempio Corrisponde
^ Inizio stringa/riga ^Ciao "Ciao Mondo" (all'inizio)
$ Fine stringa/riga Mondo$ "Ciao Mondo" (alla fine)
\b Confine parola \bgatto\b "gatto" in "Il gatto seduto" (NON "gattone")
\B Non-confine parola \Bgatt "gattone" (gatt NON al confine)
\A Inizio stringa (non riga) \ACiao Corrisponde solo se "Ciao" è proprio all'inizio
\z Fine stringa (non riga) Mondo\z Corrisponde solo se "Mondo" è proprio alla fine
\Z Fine stringa (prima del newline finale) Mondo\Z Corrisponde "Mondo" o "Mondo\n"

Esempi:

^gatto$       → Corrisponde: "gatto" (l'intera riga è "gatto")
\bgatto\b     → Corrisponde: "gatto" in "il gatto seduto" (parola intera)
\Bgatt        → Corrisponde: "gatt" in "gattone" (NON al confine)

Modalità Multilinea (flag m):

  • Senza m: ^ e $ corrispondono inizio/fine dell'intera stringa
  • Con m: ^ e $ corrispondono inizio/fine di ogni riga

Gruppi e Alternanza

Gruppi di Cattura

I gruppi di cattura (...) ricordano il testo corrispondente:

(\d+)-(\d+)   → Corrisponde: "123-456"
                Gruppo 1: "123"
                Gruppo 2: "456"

Riferimenti all'indietro (riutilizza gruppi catturati):

(\w)\1        → Corrisponde: "aa", "bb", "cc" (carattere ripetuto)
(\w+) \1      → Corrisponde: "ciao ciao" (parola ripetuta)

Gruppi Non-Cattura

Usa (?:...) quando serve raggruppare ma non serve catturare:

(?:https?://)  → Raggruppa "http://" o "https://" senza catturare

Perché usare non-cattura?

  • Prestazioni migliori (nessun overhead di memoria)
  • Riferimenti all'indietro più puliti (i gruppi numerati contano solo i gruppi di cattura)

Alternanza (OR)

Usa | per "corrisponde questo O quello":

gatto|cane    → Corrisponde: "gatto" o "cane"
gr(i|a)gio    → Corrisponde: "grigio" o "graggio"

Esempi:

(Sig|Sig\.ra|Dott)\.?  → Corrisponde: "Sig.", "Sig.ra", "Dott."
https?://              → Corrisponde: "http://" o "https://"

Asserzioni Lookaround

I lookaround sono asserzioni a larghezza zero che corrispondono a una posizione (come gli ancoraggi) ma con condizioni.

Lookahead Positivo (?=...)

Corrisponde se il pattern avanti corrisponde (ma non lo consuma):

\d(?=px)      → Corrisponde: "10" in "10px" (NON la parte "px")

Caso d'uso: Validazione password

^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$

Scomposizione:

  • (?=.*[A-Z]) - Deve contenere maiuscola
  • (?=.*[a-z]) - Deve contenere minuscola
  • (?=.*\d) - Deve contenere cifra
  • (?=.*[@$!%*?&]) - Deve contenere carattere speciale
  • .{8,} - Almeno 8 caratteri

Lookahead Negativo (?!...)

Corrisponde se il pattern avanti NON corrisponde:

\d(?!px)      → Corrisponde: "10" in "10em" (NON "10px")

Caso d'uso: Escludere certe parole

\b(?!test)\w+  → Corrisponde parole che NON iniziano con "test"

Lookbehind Positivo (?<=...)

Corrisponde se il pattern indietro corrisponde:

(?<=€)\d+     → Corrisponde: "100" in "€100" (NON la parte "€")

Caso d'uso: Estrarre prezzi

(?<=Prezzo: €)\d+,\d{2}  → Corrisponde: "29,99" in "Prezzo: €29,99"

Lookbehind Negativo (?<!...)

Corrisponde se il pattern indietro NON corrisponde:

(?<!€)\d+     → Corrisponde: "100" ma NON in "€100"

Tabella Riepilogativa:

Tipo Sintassi Descrizione Esempio
Lookahead Positivo (?=...) Corrisponde se seguito da... q(?=u) corrisponde "q" in "queen"
Lookahead Negativo (?!...) Corrisponde se NON seguito da... q(?!u) corrisponde "q" in "iraq"
Lookbehind Positivo (?<=...) Corrisponde se preceduto da... (?<=€)\d+ corrisponde "10" in "€10"
Lookbehind Negativo (?<!...) Corrisponde se NON preceduto da... (?<!€)\d+ corrisponde "10" in "10"

Gruppi di Cattura Nominati

I gruppi nominati (?<nome>...) rendono le regex più leggibili:

JavaScript:

const dateRegex = /(?<anno>\d{4})-(?<mese>\d{2})-(?<giorno>\d{2})/;
const match = '2025-01-17'.match(dateRegex);

console.log(match.groups.anno);   // "2025"
console.log(match.groups.mese);   // "01"
console.log(match.groups.giorno); // "17"

Python:

import re

pattern = r'(?P<anno>\d{4})-(?P<mese>\d{2})-(?P<giorno>\d{2})'
match = re.search(pattern, '2025-01-17')

print(match.group('anno'))   # "2025"
print(match.group('mese'))   # "01"
print(match.group('giorno')) # "17"

C#:

var pattern = @"(?<anno>\d{4})-(?<mese>\d{2})-(?<giorno>\d{2})";
var match = Regex.Match("2025-01-17", pattern);

Console.WriteLine(match.Groups["anno"].Value);   // "2025"

Gruppi Atomici e Quantificatori Possessivi

Gruppi Atomici (?>...)

Una volta corrispondente, il gruppo non fa backtrack. Previene backtracking catastrofico:

(?>\d+)bar    → Corrisponde: "123bar" (veloce)

Senza gruppo atomico:

\d+bar        → Prova: "123bar", "12bar", "1bar" (lento su mancata corrispondenza)

Quantificatori Possessivi

Greedy Possessivo Descrizione
* *+ 0 o più (nessun backtracking)
+ ++ 1 o più (nessun backtracking)
? ?+ 0 o 1 (nessun backtracking)

Caso d'uso: Previeni backtracking catastrofico su pattern complessi.


Supporto Unicode

I motori regex moderni supportano categorie e script Unicode.

Categorie Unicode \p{...}

JavaScript (ES2018+):

const letters = /\p{L}+/u;     // Qualsiasi lettera (qualsiasi lingua)
const numbers = /\p{N}+/u;     // Qualsiasi numero
const currency = /\p{Sc}/u;    // Simboli di valuta

Python:

import regex  # Nota: richiede modulo 'regex', non 're'

letters = regex.compile(r'\p{L}+')

Categorie Unicode Comuni:

Categoria Descrizione Esempio
\p{L} Lettera "a", "字", "א"
\p{N} Numero "1", "①", "一"
\p{S} Simbolo "$", "©", "♥"
\p{Sc} Simbolo valuta "$", "€", "¥"
\p{P} Punteggiatura ".", "!", "?"
\p{Z} Separatore Spazio, tab

Script Unicode:

/\p{Script=Greek}/u     → Corrisponde lettere greche: "α", "β", "γ"
/\p{Script=Cyrillic}/u  → Corrisponde cirillico: "а", "б", "в"
/\p{Script=Han}/u       → Corrisponde caratteri cinesi

Negazione:

/\P{L}+/u   → Corrisponde a qualsiasi cosa che NON sia una lettera

Modificatori e Flag

I flag cambiano come i pattern regex vengono interpretati.

Flag Nome Descrizione Esempio
i Insensibile maiuscole Ignora maiuscole /ciao/i corrisponde "Ciao"
g Globale Trova tutte le corrispondenze /gatto/g trova tutti i "gatto"
m Multilinea ^ e $ corrispondono inizi/fini riga /^ciao/m
s Dotall . corrisponde anche a newline /a.b/s corrisponde "a\nb"
u Unicode Abilita funzionalità Unicode /\p{L}+/u
x Esteso Ignora spazi bianchi (free-spacing) Permette commenti
y Sticky Corrisponde a posizione esatta Solo JavaScript

Esempi:

Insensibile maiuscole (i):

/ciao/i.test('CIAO')   // true

Globale (g):

'gatto cane gatto'.match(/gatto/g)   // ["gatto", "gatto"]

Multilinea (m):

const text = 'Riga 1\nRiga 2';
/^Riga 2/m.test(text)   // true (senza 'm': false)

Dotall (s):

/a.b/s.test('a\nb')   // true (senza 's': false)

Modificatori Inline

Applica flag a parte del pattern:

(?i)ciao       → "ciao" insensibile maiuscole
(?-i)MONDO     → "MONDO" sensibile maiuscole
(?i:ciao)      → Solo "ciao" è insensibile maiuscole

Pattern Condizionali

Sintassi: (?(condizione)vero|falso)

Esempio: Corrispondere stringhe quotate o non quotate

("|')?[^"'\r\n]*(?(1)\1)

Scomposizione:

  • ("|')? - Cattura opzionalmente virgoletta di apertura
  • [^"'\r\n]* - Corrisponde contenuto
  • (?(1)\1) - Se gruppo 1 corrispondente (virgoletta apertura), corrisponde stessa virgoletta chiusura

Corrisponde:

  • "ciao"
  • 'mondo'
  • test ✅ (nessuna virgoletta)
  • "misto' ❌ (virgolette non corrispondenti)

Commenti nelle Regex

Commenti Inline (?# commento)

\d{3}(?# prefisso)-\d{3}(?# centrale)-\d{4}(?# numero)

Modalità Free-Spacing (flag x)

Ignora spazi bianchi e permette commenti:

(?x)
  \d{3}     # prefisso
  -         # separatore
  \d{3}     # centrale
  -         # separatore
  \d{4}     # numero

Molto più leggibile per pattern complessi!

Questa sezione dimostra come usare le regex in 7 linguaggi di programmazione popolari. Ogni linguaggio ha la sua API regex, ma la sintassi dei pattern rimane per lo più consistente.

JavaScript / Node.js

Creare Pattern Regex

// Notazione letterale (più comune)
const pattern1 = /\d{3}-\d{4}/;

// Costruttore (quando il pattern è dinamico)
const pattern2 = new RegExp('\\d{3}-\\d{4}');
// Nota: I backslash devono essere escapati nelle stringhe

// Con flag
const pattern3 = /ciao/gi;  // Globale, insensibile maiuscole

Metodi String

// .match() - Trova corrispondenze
const text = 'Contatto: 123-4567 o 987-6543';
const matches = text.match(/\d{3}-\d{4}/g);
console.log(matches);  // ["123-4567", "987-6543"]

// .matchAll() - Ottieni tutte le corrispondenze con gruppi (ES2020)
const emailPattern = /([\w.-]+)@([\w.-]+\.[a-z]{2,})/gi;
const emails = 'admin@esempio.it, utente@test.org';
for (const match of emails.matchAll(emailPattern)) {
  console.log(`Utente: ${match[1]}, Dominio: ${match[2]}`);
}
// Utente: admin, Dominio: esempio.it
// Utente: utente, Dominio: test.org

// .search() - Trova posizione della prima corrispondenza
const pos = 'Ciao Mondo'.search(/Mondo/);
console.log(pos);  // 5

// .replace() - Sostituisci corrispondenze
const phone = '(+39) 333 123 4567';
const cleaned = phone.replace(/[^\d]/g, '');
console.log(cleaned);  // "393331234567"

// .replaceAll() - Sostituisci tutte le corrispondenze (ES2021)
const text2 = 'gatto cane gatto';
const result = text2.replaceAll(/gatto/g, 'uccello');
console.log(result);  // "uccello cane uccello"

// .split() - Dividi per pattern
const csv = 'mela,banana, arancia , uva';
const fruits = csv.split(/\s*,\s*/);
console.log(fruits);  // ["mela", "banana", "arancia", "uva"]

Metodi RegExp

// .test() - Restituisce booleano
const isEmail = /^[\w.-]+@[\w.-]+\.[a-z]{2,}$/i;
console.log(isEmail.test('utente@esempio.it'));  // true

// .exec() - Restituisce dettagli corrispondenza (o null)
const pattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = pattern.exec('Data: 2025-01-17');
if (match) {
  console.log(match[0]);  // "2025-01-17" (corrispondenza completa)
  console.log(match[1]);  // "2025" (gruppo 1)
  console.log(match[2]);  // "01" (gruppo 2)
  console.log(match[3]);  // "17" (gruppo 3)
}

Gruppi Nominati (ES2018+)

const pattern = /(?<anno>\d{4})-(?<mese>\d{2})-(?<giorno>\d{2})/;
const match = '2025-01-17'.match(pattern);

console.log(match.groups.anno);   // "2025"
console.log(match.groups.mese);   // "01"
console.log(match.groups.giorno); // "17"

// Riferimenti nominati all'indietro
const dupeWord = /\b(?<parola>\w+)\s+\k<parola>\b/i;
console.log(dupeWord.test('ciao ciao'));  // true

Supporto Unicode (ES2018+)

// Corrisponde qualsiasi lettera (incluse accentate, cinesi, arabe, ecc.)
const letters = /\p{L}+/u;
console.log(letters.test('caffè'));   // true
console.log(letters.test('你好'));    // true

// Corrisponde emoji
const emoji = /\p{Emoji}/u;
console.log(emoji.test('Ciao 👋'));  // true

Python

Il Modulo re

import re

# Compila pattern (raccomandato per riutilizzo)
pattern = re.compile(r'\d{3}-\d{4}')

# Oppure usa direttamente
re.search(r'\d{3}-\d{4}', 'Chiama 123-4567')

Funzioni Core

import re

# re.search() - Trova prima corrispondenza
match = re.search(r'\d{3}-\d{4}', 'Contatto: 123-4567 o 987-6543')
if match:
    print(match.group())  # "123-4567"
    print(match.start())  # 10 (posizione)
    print(match.end())    # 18

# re.match() - Corrisponde all'INIZIO della stringa
match = re.match(r'\d+', '123 Via Roma')
print(match.group() if match else None)  # "123"

match = re.match(r'\d+', 'Via Roma 123')
print(match)  # None (non inizia con cifra)

# re.fullmatch() - Corrisponde INTERA stringa
result = re.fullmatch(r'\d{3}-\d{4}', '123-4567')
print(bool(result))  # True

result = re.fullmatch(r'\d{3}-\d{4}', 'Chiama 123-4567')
print(bool(result))  # False (testo extra)

# re.findall() - Trova tutte le corrispondenze (restituisce lista)
text = 'Prezzi: €10, €25, €100'
prices = re.findall(r'€(\d+)', text)
print(prices)  # ['10', '25', '100']

# re.finditer() - Trova tutte le corrispondenze (restituisce iteratore)
for match in re.finditer(r'€(\d+)', text):
    print(f'Trovato €{match.group(1)} alla posizione {match.start()}')
# Trovato €10 alla posizione 8
# Trovato €25 alla posizione 13
# Trovato €100 alla posizione 18

# re.sub() - Sostituisci corrispondenze
phone = '(+39) 333 123 4567'
cleaned = re.sub(r'[^\d]', '', phone)
print(cleaned)  # "393331234567"

# re.split() - Dividi per pattern
csv = 'mela,banana, arancia , uva'
fruits = re.split(r'\s*,\s*', csv)
print(fruits)  # ['mela', 'banana', 'arancia', 'uva']

Gruppi e Gruppi Nominati

import re

# Gruppi numerati
pattern = r'(\d{4})-(\d{2})-(\d{2})'
match = re.search(pattern, 'Data: 2025-01-17')
if match:
    print(match.group(0))  # "2025-01-17" (corrispondenza completa)
    print(match.group(1))  # "2025"
    print(match.group(2))  # "01"
    print(match.group(3))  # "17"
    print(match.groups())  # ('2025', '01', '17')

# Gruppi nominati (?P<nome>...)
pattern = r'(?P<anno>\d{4})-(?P<mese>\d{2})-(?P<giorno>\d{2})'
match = re.search(pattern, '2025-01-17')
if match:
    print(match.group('anno'))    # "2025"
    print(match.group('mese'))    # "01"
    print(match.group('giorno'))  # "17"
    print(match.groupdict())      # {'anno': '2025', 'mese': '01', 'giorno': '17'}

Flag

import re

# Insensibile maiuscole
re.search(r'ciao', 'CIAO', re.IGNORECASE)  # o re.I

# Multilinea (^ e $ corrispondono inizi/fini riga)
re.search(r'^Riga 2', 'Riga 1\nRiga 2', re.MULTILINE)  # o re.M

# Dotall (. corrisponde newline)
re.search(r'a.b', 'a\nb', re.DOTALL)  # o re.S

# Verbose (modalità free-spacing con commenti)
pattern = re.compile(r'''
    \d{3}     # prefisso
    -         # separatore
    \d{3}     # centrale
    -         # separatore
    \d{4}     # numero
''', re.VERBOSE)  # o re.X

# Combina flag con |
pattern = re.compile(r'ciao', re.IGNORECASE | re.MULTILINE)

Sostituzione con Funzioni

import re

# Usa funzione per sostituzioni dinamiche
def double_number(match):
    num = int(match.group())
    return str(num * 2)

text = 'Ho 5 mele e 10 arance'
result = re.sub(r'\d+', double_number, text)
print(result)  # "Ho 10 mele e 20 arance"

# Con gruppi nominati
def format_name(match):
    return f"{match.group('cognome').upper()}, {match.group('nome')}"

pattern = r'(?P<nome>\w+)\s+(?P<cognome>\w+)'
text = 'Mario Rossi'
result = re.sub(pattern, format_name, text)
print(result)  # "ROSSI, Mario"

PHP

Funzioni PCRE

<?php

// preg_match() - Trova prima corrispondenza
$pattern = '/\d{3}-\d{4}/';
$text = 'Contatto: 123-4567 o 987-6543';

if (preg_match($pattern, $text, $matches)) {
    echo $matches[0];  // "123-4567"
}

// preg_match_all() - Trova tutte le corrispondenze
preg_match_all('/\d{3}-\d{4}/', $text, $matches);
print_r($matches[0]);  // ["123-4567", "987-6543"]

// preg_replace() - Sostituisci corrispondenze
$phone = '(+39) 333 123 4567';
$cleaned = preg_replace('/[^\d]/', '', $phone);
echo $cleaned;  // "393331234567"

// preg_split() - Dividi per pattern
$csv = 'mela,banana, arancia , uva';
$fruits = preg_split('/\s*,\s*/', $csv);
print_r($fruits);  // ["mela", "banana", "arancia", "uva"]

// preg_grep() - Filtra array per pattern
$words = ['mela', 'banana', 'albicocca', 'arancia'];
$aWords = preg_grep('/^a/', $words);
print_r($aWords);  // ["albicocca", "arancia"]
?>

Gruppi Nominati

<?php
$pattern = '/(?P<anno>\d{4})-(?P<mese>\d{2})-(?P<giorno>\d{2})/';
$text = '2025-01-17';

if (preg_match($pattern, $text, $matches)) {
    echo $matches['anno'];   // "2025"
    echo $matches['mese'];   // "01"
    echo $matches['giorno']; // "17"
}
?>

Modificatori (Flag)

<?php
// i - Insensibile maiuscole
preg_match('/ciao/i', 'CIAO');  // Corrisponde

// m - Multilinea
preg_match('/^Riga 2/m', "Riga 1\nRiga 2");  // Corrisponde

// s - Dotall (. corrisponde newline)
preg_match('/a.b/s', "a\nb");  // Corrisponde

// x - Free-spacing (ignora spazi bianchi)
$pattern = '/
    \d{3}     # prefisso
    -         # separatore
    \d{3}     # centrale
    -         # separatore
    \d{4}     # numero
/x';

// u - Supporto UTF-8
preg_match('/\w+/u', 'caffè');  // Corrisponde (include è)

// Combina modificatori
preg_match('/ciao/imu', $text);
?>

Sostituzione con Callback

<?php
$text = 'Ho 5 mele e 10 arance';

$result = preg_replace_callback('/\d+/', function($matches) {
    return (int)$matches[0] * 2;
}, $text);

echo $result;  // "Ho 10 mele e 20 arance"
?>

C# (.NET)

Classe Regex

using System;
using System.Text.RegularExpressions;

// Metodi statici (uso semplice)
string text = "Contatto: 123-4567 o 987-6543";
Match match = Regex.Match(text, @"\d{3}-\d{4}");
if (match.Success)
{
    Console.WriteLine(match.Value);  // "123-4567"
}

// Trova tutte le corrispondenze
MatchCollection matches = Regex.Matches(text, @"\d{3}-\d{4}");
foreach (Match m in matches)
{
    Console.WriteLine(m.Value);
}
// Output:
// 123-4567
// 987-6543

// Sostituisci
string phone = "(+39) 333 123 4567";
string cleaned = Regex.Replace(phone, @"[^\d]", "");
Console.WriteLine(cleaned);  // "393331234567"

// Dividi
string csv = "mela,banana, arancia , uva";
string[] fruits = Regex.Split(csv, @"\s*,\s*");
// ["mela", "banana", "arancia", "uva"]

Regex Compilata (Prestazioni Migliori)

using System.Text.RegularExpressions;

// Compila per riutilizzo (molto più veloce per uso ripetuto)
Regex pattern = new Regex(@"\d{3}-\d{4}", RegexOptions.Compiled);

string text = "Contatto: 123-4567";
Match match = pattern.Match(text);
if (match.Success)
{
    Console.WriteLine(match.Value);
}

RegexOptions (Flag)

using System.Text.RegularExpressions;

// Insensibile maiuscole
Regex.IsMatch("CIAO", "ciao", RegexOptions.IgnoreCase);

// Multilinea
Regex.Match("Riga 1\nRiga 2", "^Riga 2", RegexOptions.Multiline);

// Singleline (. corrisponde newline)
Regex.Match("a\nb", "a.b", RegexOptions.Singleline);

// Compilata (prestazioni migliori)
var pattern = new Regex(@"\d+", RegexOptions.Compiled);

// Combina opzioni
var opts = RegexOptions.IgnoreCase | RegexOptions.Multiline;
Regex.Match(text, pattern, opts);

Gruppi Nominati

using System;
using System.Text.RegularExpressions;

string pattern = @"(?<anno>\d{4})-(?<mese>\d{2})-(?<giorno>\d{2})";
Match match = Regex.Match("2025-01-17", pattern);

if (match.Success)
{
    Console.WriteLine(match.Groups["anno"].Value);   // "2025"
    Console.WriteLine(match.Groups["mese"].Value);   // "01"
    Console.WriteLine(match.Groups["giorno"].Value); // "17"
}

Sostituzione con MatchEvaluator

using System;
using System.Text.RegularExpressions;

string text = "Ho 5 mele e 10 arance";

string result = Regex.Replace(text, @"\d+", match =>
{
    int num = int.Parse(match.Value);
    return (num * 2).ToString();
});

Console.WriteLine(result);  // "Ho 10 mele e 20 arance"

Java

Classi Pattern e Matcher

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

// Compila pattern
Pattern pattern = Pattern.compile("\\d{3}-\\d{4}");
String text = "Contatto: 123-4567 o 987-6543";

// Crea matcher
Matcher matcher = pattern.matcher(text);

// Trova prima corrispondenza
if (matcher.find()) {
    System.out.println(matcher.group());  // "123-4567"
}

// Trova tutte le corrispondenze
matcher.reset();  // Resetta all'inizio
while (matcher.find()) {
    System.out.println(matcher.group());
}
// Output:
// 123-4567
// 987-6543

Metodi String

// matches() - Verifica se INTERA stringa corrisponde
boolean isPhone = "123-4567".matches("\\d{3}-\\d{4}");
System.out.println(isPhone);  // true

// replaceAll() - Sostituisci tutte le corrispondenze
String phone = "(+39) 333 123 4567";
String cleaned = phone.replaceAll("[^\\d]", "");
System.out.println(cleaned);  // "393331234567"

// replaceFirst() - Sostituisci prima corrispondenza
String text = "gatto cane gatto";
String result = text.replaceFirst("gatto", "uccello");
System.out.println(result);  // "uccello cane gatto"

// split() - Dividi per pattern
String csv = "mela,banana, arancia , uva";
String[] fruits = csv.split("\\s*,\\s*");
// ["mela", "banana", "arancia", "uva"]

Flag Pattern

import java.util.regex.Pattern;

// Insensibile maiuscole
Pattern pattern = Pattern.compile("ciao", Pattern.CASE_INSENSITIVE);

// Multilinea
Pattern.compile("^Riga 2", Pattern.MULTILINE);

// Dotall (. corrisponde newline)
Pattern.compile("a.b", Pattern.DOTALL);

// Commenti (free-spacing)
Pattern.compile("""
    \\d{3}     # prefisso
    -          # separatore
    \\d{3}     # centrale
    -          # separatore
    \\d{4}     # numero
    """, Pattern.COMMENTS);

// Combina flag
int flags = Pattern.CASE_INSENSITIVE | Pattern.MULTILINE;
Pattern.compile("pattern", flags);

Gruppi Nominati

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

Pattern pattern = Pattern.compile("(?<anno>\\d{4})-(?<mese>\\d{2})-(?<giorno>\\d{2})");
Matcher matcher = pattern.matcher("2025-01-17");

if (matcher.find()) {
    System.out.println(matcher.group("anno"));   // "2025"
    System.out.println(matcher.group("mese"));   // "01"
    System.out.println(matcher.group("giorno")); // "17"
}

Sostituzione Avanzata

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

String text = "Ho 5 mele e 10 arance";
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(text);

StringBuffer result = new StringBuffer();
while (matcher.find()) {
    int num = Integer.parseInt(matcher.group());
    matcher.appendReplacement(result, String.valueOf(num * 2));
}
matcher.appendTail(result);

System.out.println(result);  // "Ho 10 mele e 20 arance"

Go (Golang)

Il Package regexp

package main

import (
    "fmt"
    "regexp"
)

func main() {
    // Compila pattern
    pattern := regexp.MustCompile(`\d{3}-\d{4}`)
    text := "Contatto: 123-4567 o 987-6543"

    // Trova prima corrispondenza
    match := pattern.FindString(text)
    fmt.Println(match)  // "123-4567"

    // Trova tutte le corrispondenze
    matches := pattern.FindAllString(text, -1)
    fmt.Println(matches)  // [123-4567 987-6543]

    // Verifica se corrisponde
    isMatch := pattern.MatchString("123-4567")
    fmt.Println(isMatch)  // true

    // Sostituisci tutto
    phone := "(+39) 333 123 4567"
    cleaned := regexp.MustCompile(`[^\d]`).ReplaceAllString(phone, "")
    fmt.Println(cleaned)  // "393331234567"

    // Dividi
    csv := "mela,banana, arancia , uva"
    fruits := regexp.MustCompile(`\s*,\s*`).Split(csv, -1)
    fmt.Println(fruits)  // [mela banana arancia uva]
}

Submatch (Gruppi)

package main

import (
    "fmt"
    "regexp"
)

func main() {
    pattern := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)
    text := "Data: 2025-01-17"

    // FindStringSubmatch restituisce [completo, gruppo1, gruppo2, ...]
    matches := pattern.FindStringSubmatch(text)
    if matches != nil {
        fmt.Println(matches[0])  // "2025-01-17" (corrispondenza completa)
        fmt.Println(matches[1])  // "2025" (gruppo 1)
        fmt.Println(matches[2])  // "01" (gruppo 2)
        fmt.Println(matches[3])  // "17" (gruppo 3)
    }

    // FindAllStringSubmatch per tutte le corrispondenze
    text2 := "Date: 2025-01-17 e 2024-12-31"
    allMatches := pattern.FindAllStringSubmatch(text2, -1)
    for _, match := range allMatches {
        fmt.Printf("Anno: %s, Mese: %s, Giorno: %s\n", match[1], match[2], match[3])
    }
    // Anno: 2025, Mese: 01, Giorno: 17
    // Anno: 2024, Mese: 12, Giorno: 31
}

Gruppi Nominati

package main

import (
    "fmt"
    "regexp"
)

func main() {
    pattern := regexp.MustCompile(`(?P<anno>\d{4})-(?P<mese>\d{2})-(?P<giorno>\d{2})`)
    text := "2025-01-17"

    match := pattern.FindStringSubmatch(text)
    if match != nil {
        // Ottieni indici gruppi nominati
        names := pattern.SubexpNames()
        result := make(map[string]string)
        for i, name := range names {
            if i != 0 && name != "" {
                result[name] = match[i]
            }
        }
        fmt.Println(result["anno"])   // "2025"
        fmt.Println(result["mese"])   // "01"
        fmt.Println(result["giorno"]) // "17"
    }
}

Sostituzione con Funzioni

package main

import (
    "fmt"
    "regexp"
    "strconv"
)

func main() {
    text := "Ho 5 mele e 10 arance"
    pattern := regexp.MustCompile(`\d+`)

    result := pattern.ReplaceAllStringFunc(text, func(s string) string {
        num, _ := strconv.Atoi(s)
        return strconv.Itoa(num * 2)
    })

    fmt.Println(result)  // "Ho 10 mele e 20 arance"
}

Ruby

Letterali Regex

# Notazione letterale
pattern = /\d{3}-\d{4}/

# Con flag
pattern_ci = /ciao/i  # Insensibile maiuscole
pattern_multi = /^riga/m  # Multilinea

# Costruttore (per pattern dinamici)
pattern = Regex.new('\d{3}-\d{4}')

Metodi String

text = 'Contatto: 123-4567 o 987-6543'

# match() - Restituisce MatchData o nil
match = text.match(/\d{3}-\d{4}/)
if match
  puts match[0]  # "123-4567"
end

# scan() - Trova tutte le corrispondenze
matches = text.scan(/\d{3}-\d{4}/)
puts matches  # ["123-4567", "987-6543"]

# =~ operatore - Restituisce indice della prima corrispondenza
index = text =~ /\d{3}-\d{4}/
puts index  # 10

# sub() - Sostituisci prima corrispondenza
result = 'gatto cane gatto'.sub(/gatto/, 'uccello')
puts result  # "uccello cane gatto"

# gsub() - Sostituisci tutte le corrispondenze
phone = '(+39) 333 123 4567'
cleaned = phone.gsub(/[^\d]/, '')
puts cleaned  # "393331234567"

# split() - Dividi per pattern
csv = 'mela,banana, arancia , uva'
fruits = csv.split(/\s*,\s*/)
puts fruits  # ["mela", "banana", "arancia", "uva"]

Gruppi di Cattura

pattern = /(\d{4})-(\d{2})-(\d{2})/
match = '2025-01-17'.match(pattern)

if match
  puts match[0]  # "2025-01-17" (corrispondenza completa)
  puts match[1]  # "2025" (gruppo 1)
  puts match[2]  # "01" (gruppo 2)
  puts match[3]  # "17" (gruppo 3)
end

Gruppi Nominati

pattern = /(?<anno>\d{4})-(?<mese>\d{2})-(?<giorno>\d{2})/
match = '2025-01-17'.match(pattern)

if match
  puts match[:anno]   # "2025"
  puts match[:mese]   # "01"
  puts match[:giorno] # "17"
end

Sostituzione con Blocchi

text = 'Ho 5 mele e 10 arance'

result = text.gsub(/\d+/) { |num| (num.to_i * 2).to_s }
puts result  # "Ho 10 mele e 20 arance"

# Con gruppi nominati
pattern = /(?<nome>\w+)\s+(?<cognome>\w+)/
text = 'Mario Rossi'

result = text.gsub(pattern) do |match|
  m = Regexp.last_match
  "#{m[:cognome].upcase}, #{m[:nome]}"
end
puts result  # "ROSSI, Mario"

Flag

# i - Insensibile maiuscole
/ciao/i.match('CIAO')  # Corrisponde

# m - Multilinea (. corrisponde newline)
/a.b/m.match("a\nb")  # Corrisponde

# x - Free-spacing (ignora spazi bianchi)
pattern = /
  \d{3}     # prefisso
  -         # separatore
  \d{3}     # centrale
  -         # separatore
  \d{4}     # numero
/x

# o - Compila una volta (ottimizzazione)
pattern = /\d+/o

Il Trova e Sostituisci di Visual Studio Code (Ctrl/Cmd+H) supporta le regex con potenti capacità di trasformazione. Questa sezione mostra 28 esempi pratici che gli sviluppatori usano ogni giorno.

Accedere a Trova e Sostituisci

Scorciatoie da Tastiera:

  • Trova: Ctrl+F (Windows/Linux) / Cmd+F (Mac)
  • Sostituisci: Ctrl+H (Windows/Linux) / Cmd+H (Mac)
  • Abilita Regex: Clicca il pulsante .* o premi Alt+R

Suggerimenti:

  • Usa Ctrl+Enter (Cmd+Enter) per sostituire tutto
  • Anteprima delle corrispondenze prima di sostituire (si evidenziano in giallo)
  • Usa F3 / Shift+F3 per navigare tra le corrispondenze

Trasformazioni Maiuscole/Minuscole

VS Code supporta sequenze speciali di sostituzione per conversione maiuscole:

Sequenza Effetto Esempio
\l Minuscola carattere successivo \l
\u Maiuscola carattere successivo \u
\L Minuscola tutti i caratteri seguenti \L
\U Maiuscola tutti i caratteri seguenti \U
\E Termina trasformazione maiuscole \U\E

Esempio 1: Capitalizza Prima Lettera

Trova:

\b(\w)(\w*)

Sostituisci:

\u$1$2

Prima:

ciao mondo

Dopo:

Ciao Mondo

Questa sezione fornisce oltre 25 pattern regex pronti all'uso.

Validazione Email

^[\w.-]+@[\w.-]+\.[a-z]{2,}$

Numeri di Telefono (Italia)

^(\+?39)?[-.\s]?\(?([0-9]{3})\)?[-.\s]?([0-9]{3})[-.\s]?([0-9]{4})$

Date (ISO 8601)

^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$

URL

^https?://(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b

Indirizzi IPv4

^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$

Colori Hex

^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$

Password Forte

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$

Nome Utente (3-16 caratteri)

^[a-zA-Z0-9_-]{3,16}$

UUID v4

^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$

E altri 15+ pattern con documentazione completa!

Applicazioni regex del mondo reale nello sviluppo.

Validazione Form

const validators = {
  email: /^[\w.-]+@[\w.-]+\.[a-z]{2,}$/i,
  phone: /^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$/
};

Estrazione Dati

Estrai email dal testo:

import re
emails = re.findall(r'[\w.-]+@[\w.-]+\.[a-z]{2,}', text)

Parsing Log

pattern = r'(?P<ip>[\d.]+).+(?P<status>\d{3})'

Refactoring Codice

Converti vecchie chiamate API in VS Code:

Trova: apiClient\.get\('([^']+)'\)
Sostituisci: fetch('$1').then(r => r.json())

Errori Comuni

1. Dimenticare di Escapare Caratteri Speciali

❌ Sbagliato: file.txt
✅ Corretto: file\.txt

2. Greedy vs Lazy

❌ Greedy: <.*> corrisponde intero <div>testo</div>
✅ Lazy: <.*?> corrisponde <div> e </div> separatamente

3. Non Usare Ancoraggi

/\d{3}/ corrisponde "123" in "abc123def"
/^\d{3}$/ corrisponde solo esattamente "123"

Suggerimenti Prestazioni

  1. Usa classi caratteri specifiche invece di .
  2. Ancora i pattern quando possibile
  3. Evita quantificatori annidati (backtracking catastrofico)
  4. Usa gruppi atomici per prestazioni
  5. Compila i pattern per riutilizzo

Debug

  1. Testa su regex101.com
  2. Usa modalità verbose con commenti
  3. Dividi pattern complessi in parti
  4. Testa casi limite

Strumenti Online

Tester Regex

  • regex101.com - Miglior tester con spiegazioni
  • regexr.com - Builder visuale regex
  • regexpal.com - Test semplice e veloce

Visualizzatori

  • debuggex.com - Diagrammi railroad
  • regexper.com - Strumento visuale

Risorse Didattiche

  • regexone.com - Lezioni interattive
  • regexlearn.com - Guida passo-passo
  • regular-expressions.info - Documentazione

Estensioni IDE

  • Regex Previewer (VS Code)
  • Regex Tester (VS Code)

Classi Caratteri

Pattern Corrisponde
\d Cifra [0-9]
\w Word [a-zA-Z0-9_]
\s Spazio bianco
. Qualsiasi carattere

Quantificatori

Pattern Significato
* 0 o più
+ 1 o più
? 0 o 1
{n} Esattamente n

Ancoraggi

Pattern Significato
^ Inizio riga
$ Fine riga
\b Confine parola

Flag

Flag Significato
i Insensibile maiuscole
g Globale
m Multilinea
s Dotall

Domande Generali

D: Qual è la differenza tra quantificatori greedy e lazy?

R: Greedy corrisponde al massimo possibile. Lazy (*?, +?) corrisponde al minimo possibile.

D: Come corrispondo a un punto letterale?

R: Escapalo con backslash: \.

D: Cos'è il backtracking catastrofico?

R: Quando la regex prova molte combinazioni, causando lentezza. Evita quantificatori annidati come (a+)+.

D: Le regex possono validare perfettamente un'email?

R: No. Usa regex per formato base, poi verifica via email.

D: Come corrispondo su più righe?

R: Usa il flag s, o usa [\s\S]* invece di .*.

Specifico VS Code

D: Come sostituisco con maiuscole in VS Code?

R: Usa \u (maiuscola successiva), \U (maiuscola tutto).

D: Posso usare regex nella ricerca file di VS Code?

R: Sì! Premi Ctrl+Shift+F e abilita regex (Alt+R).

Estensione Chrome Regex Data Extractor

Il nostro Regex Data Extractor ti aiuta a estrarre dati da pagine web usando i pattern di questa guida.

Funzionalità Chiave

  • Libreria Pattern: Pattern pre-costruiti
  • Test in Tempo Reale: Testa regex su qualsiasi pagina web
  • Esportazione Multi-Formato: CSV, JSON, Excel, PDF
  • Estrazione Batch: Estrai da più pagine

Esempio: Estrarre Email

  1. Installa Regex Data Extractor
  2. Naviga su qualsiasi pagina web
  3. Clicca l'icona dell'estensione
  4. Inserisci pattern: [\w.-]+@[\w.-]+\.[a-z]{2,}
  5. Clicca "Estrai"
  6. Esporta in CSV/JSON

Esempio: Estrarre Prezzi

Pattern: €([0-9]{1,3}(?:\.?[0-9]{3})*,?[0-9]{2})
Cattura: €1.234,56, €99,99

Suggerimenti Pro

  • Salva pattern usati frequentemente
  • Usa gruppi nominati per dati strutturati
  • Testa prima i pattern
  • Esporta per analisi dati

Ottieni Regex Data Extractor →

regexespressioni regolaricheat sheetpatterntutorialvs codepythonjavascriptphp

Last updated: 16 gennaio 2025