DanLevy.net

Quiz: Padronanza delle espressioni regolari

Riesci a domare qualche espressione regolare selvaggia?

Pronto a lottare con alcune Espressioni Regolari? 🤼‍♂️

Metti alla prova la tua conoscenza delle RegEx con domande che coprono pattern di base, quantificatori, gruppi e quelle insidiose asserzioni look‑around. Dalla semplice corrispondenza di stringhe alla complessa validazione di pattern – riesci a individuare la regex corretta?

Cosa corrisponde?

'cat CAT Cat'.match(/cat/g)

Questo pattern usa g, ma non i:

  • g trova tutte le corrispondenze
  • Senza i, il matching è sensibile al caso

Senza il flag i, solo “cat” in minuscolo corrisponde.

È particolarmente utile quando si gestiscono input utente o HTML dove il caso può variare.

Scopri di più sui flag RegExp

Cosa restituirà questo codice?

const words = ['cat', 'hat', 'what', 'bat'];
words.filter(word => word.match(/^[ch]at/))

Il pattern /^[ch]at/ corrisponde alle stringhe che:

  • Iniziano (^) con ‘c’ o ‘h’ (ecco cosa significa [ch] – una classe di caratteri che accetta un solo carattere)
  • Sono seguite letteralmente da ‘at’

Pertanto, solo “cat” e “hat” soddisfano questo pattern. Il metodo filter() conserva solo gli elementi corrispondenti.

Maggiori informazioni sulle classi di caratteri su MDN

Cosa corrisponderà questo?

'<div>Hello</div><div>World</div>'.match(/<div>.*?<\/div>/g)

Il pattern /<div>.*?<\/div>/g utilizza il matching non‑greedy con *?, che significa:

  • Corrispondi <div>
  • Corrispondi qualsiasi carattere (.*) ma il meno possibile (?)
  • Fino a trovare </div>
  • Il flag g fa sì che vengano trovate tutte le occorrenze

Senza il ?, il greedy .* corrisponderebbe a tutto, dal primo <div> all’ultimo </div>, producendo un’unica corrispondenza grande. Con ?, corrisponde a ciascuna coppia separatamente.

Scopri di più sul matching greedy vs lazy

Cosa restituirà?

'hello\nworld'.match(/\w+/g)

Il pattern \w+ corrisponde a uno o più caratteri di parola. Anche se nella stringa c’è un newline, \w corrisponde a:

  • Lettere (a-z, A-Z)
  • Numeri (0-9)
  • Underscore (_)

Quindi il newline funge da confine di parola, e otteniamo due corrispondenze. Se avessimo usato .*, non corrisponderebbe al newline per impostazione predefinita (bisognerebbe il flag s per farlo).

Scopri di più sui metacaratteri

Cosa corrisponderà questo?

'$100 and €50'.match(/\d+(?=[\$€])/g)

Questo pattern non corrisponde a nulla perché il look-ahead è al contrario! Se vuoi cifre precedute da $ o , usa un look-behind: /(?<=[\$€])\d+/g.

I look-ahead controllano cosa viene dopo la posizione corrente. Il pattern così scritto cerca:

  • Una o più cifre (\d+)
  • Seguite da ((?=...)) oppure $ o € ([\$€])

Poiché non ci sono numeri seguiti da simboli di valuta (sono preceduti da essi), non otteniamo corrispondenze.

Scopri di più sulle asserzioni look-ahead

Cosa corrisponderà?

'cat cats category'.match(/\bcat\b/g)

Il \b rappresenta un confine di parola, che corrisponde:

  • Tra un carattere di parola e un carattere non‑parola
  • All’inizio/fine della stringa se c’è un carattere di parola

Quindi /\bcat\b/ corrisponde a “cat” solo quando è una parola completa, non parte di un’altra parola.

  • ✅ “cat” (circondato da spazi)
  • ❌ “cats” (nessun confine dopo “cat”)
  • ❌ “category” (nessun confine dopo “cat”)

Scopri di più sui confini di parola

Qual è l’output?

'banana'.match(/a/g)

Il flag g (global) cambia il comportamento di match():

  • Senza g: restituisce la prima corrispondenza con i gruppi di cattura
  • Con g: restituisce un array di tutte le stringhe corrispondenti

In questo caso, trova tutte le occorrenze di “a” in “banana”.

Nota: se ti servono sia tutte le corrispondenze CHE i gruppi di cattura, usa matchAll() o il metodo exec() in un ciclo.

Scopri di più sul flag globale

Cosa corrisponde a questo modello?

'abc123 def456'.match(/(?<!abc)\d+/g)

Il look-behind negativo (?<!abc) garantisce che le cifre non siano precedute da “abc”:

  • ❌ “123” (preceduto da “abc”)
  • ✅ “23” (preceduto da “abc1”)
  • ✅ “456” (preceduto da “def”)

JavaScript supporta le asserzioni look-behind nei motori moderni. Questo esempio usa un look-behind a lunghezza fissa: abc è sempre di tre caratteri. Il look-behind a lunghezza variabile è l’aspetto più complicato e dipende dal motore.

Nota: il supporto al look-behind è relativamente recente in JavaScript. Controlla la compatibilità del browser se devi supportare browser più vecchi.

Cosa restituirà?

'2029-12-31'.match(/(\d{4})-(\d{2})-(\d{2})/).slice(1)

Il pattern utilizza tre gruppi di cattura:

  1. (\d{4}) cattura l’anno
  2. (\d{2}) cattura il mese
  3. (\d{2}) cattura il giorno

match() senza il flag g restituisce:

  • Indice 0: Corrispondenza completa
  • Indice 1+: Gruppi di cattura

slice(1) è un trucco comune per ottenere solo i gruppi di cattura.

Maggiori informazioni su gruppi e cattura

Quale sarà il risultato di questo?

"123aBc".match(/^\d+(?![a-z])/ig)

Il look-ahead negativo (?![a-z]) assicura che non ci siano lettere minuscole dopo le cifre. Poiché la parte “3aBc” contiene una lettera minuscola dopo le cifre, la sua porzione non corrisponde. Quindi solo l’inizio “12” corrisponde.

Approfondisci il look-ahead negativo

Cosa restituisce?

'a,b,c'.split(/(?<=,)/)

Il pattern /(?<=,)/ è un look-behind che corrisponde dopo una virgola:

  • a, (dopo la virgola)
  • b, (dopo la virgola)
  • c (nessuna virgola dopo)

Il look-behind non consuma la virgola, quindi la virgola rimane collegata al segmento precedente nel risultato dello split.

Questo è utile quando vuoi dividere una stringa in base a ciò che la precede senza perdere il(i) carattere(i) di split.

Scopri di più sulle asserzioni look-behind

Cosa corrisponde?

'$100'.match(/$\d+/)

I caratteri speciali devono essere escapati con \\ per corrispondere letteralmente:

  • $ è un carattere speciale (fine della stringa)
  • Per corrispondere a un segno di dollaro letterale, escapalo: \\$

Caratteri comuni che necessitano di escape:

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

Senza escape, molti caratteri speciali hanno significati regex che potrebbero non essere quelli desiderati.

Scopri di più su come escapare i caratteri speciali

Cosa viene abbinato?

'$100'.match(/(?<=\$)\d+/)

Il look-behind positivo (?<=\$) assicura che le cifre siano precedute da un simbolo di dollaro:

  • (?<=\$): Look-behind per il simbolo di dollaro
  • \d+: Corrisponde a una o più cifre

Le asserzioni look-behind non consumano caratteri; controllano solo ciò che precede. È utile quando vuoi abbinare qualcosa in base a ciò che lo precede senza includere la parte precedente.

Scopri di più sulle asserzioni look-behind

Cosa viene abbinato?

'<b>bold</b>'.match(/<b>(.*?)<\/b>/).slice(1)

Il pattern utilizza il matching lazy con *?:

  • <b>: corrisponde al tag di apertura
  • (.*?): cattura qualsiasi carattere (lazy)
  • </b>: corrisponde al tag di chiusura

Il ? dopo * lo rende lazy, abbinando il minor numero possibile di caratteri. Senza ? sarebbe greedy e abbinerebbe il più possibile.

slice(1) restituisce solo il gruppo catturato.

Scopri di più su greedy vs lazy matching

Cosa corrisponde?

'😀 🙂'.match(/\p{Emoji}/gu)

La flag u abilita:

  • le escape di proprietà Unicode (\p{...})
  • la corretta gestione delle coppie surrogate

Senza u, le emoji e altri caratteri Unicode potrebbero non corrispondere correttamente. Il pattern \p{Emoji} corrisponde ai caratteri con la proprietà Unicode Emoji. In questa stringa, ciò significa le due pictogrammi emoji.

Nota: le escape di proprietà Unicode richiedono la flag u.

Approfondisci la modalità Unicode

Scusate in anticipo! 😈
Quale password corrisponde a questo pattern?

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

Non scrivete nulla del genere in produzione! 😅

Questo pattern utilizza più look-ahead positivi per imporre:

  • Almeno una lettera maiuscola: (?=.*[A-Z])
  • Almeno una lettera minuscola: (?=.*[a-z])
  • Almeno una cifra: (?=.*\d)
  • Almeno un carattere speciale: (?=.*[!@#$%^&*])
  • Lunghezza minima di 8: .{8,}

I look-ahead sono perfetti per la validazione delle password perché possono verificare più criteri senza consumare caratteri.

Scopri di più sui pattern di validazione delle password

Come è andata? 🧐

Le espressioni regolari possono essere una bestia da domare, ma sono incredibilmente potenti una volta che le prendi in mano (e tutta la sintassi più recente). Continua a esercitarti, e diventerai un maestro di RegEx in men che non si dica! 🧙‍♂️

Cerchi una pausa dopo tutto quel RegEx?
Pftt, ricorda: pausa dopo le competenze!

Vai al la mia palestra per affrontare altre sfide! 💪