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:
gtrova 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.
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.
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
gfa 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.
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).
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.
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”)
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.
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:
(\d{4})cattura l’anno(\d{2})cattura il mese(\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.
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.
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.
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.
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.
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.
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.
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.
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! 💪