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 (servirebbe il flag s per farlo).
Cosa corrisponderà questo?
'$100 and €50'.match(/\d+(?=[\$€])/g)Questo pattern non trova corrispondenze perché controlla i simboli di valuta dopo le cifre, mentre nell’input le precedono. 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 flag i rende [a-z] valido per lettere ASCII sia maiuscole sia minuscole. Il quantificatore greedy \d+ prova prima 123, ma il look-ahead fallisce davanti ad a. Il motore torna indietro a 12: il carattere successivo è 3, non una lettera, quindi la corrispondenza riesce.
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)Il flag u abilita:
- le escape di proprietà Unicode (
\p{...}) - la corretta gestione delle coppie surrogate
Il flag u abilita la modalità Unicode; nei motori moderni anche v abilita una modalità Unicode con funzionalità aggiuntive.
Il pattern \p{Emoji} corrisponde ai caratteri con la proprietà Unicode Emoji. In questa stringa, ciò significa i due pittogrammi emoji.
Nota: le escape di proprietà Unicode richiedono la modalità Unicode, attivata con u oppure v.
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! 💪
