Regex in JavaScript
Impara le espressioni regolari (regex) in JavaScript: pattern, flag, metodi principali e blocchi di base per cercare e validare il testo.
Introduzione alle espressioni regolari (Regex) in JavaScript
Le espressioni regolari, comunemente note come regex, sono sequenze di caratteri che formano pattern di ricerca. Sono strumenti essenziali nella programmazione per elaborare testo: ricerca, modifica e manipolazione di dati string. La regex viene utilizzata in vari ambiti come la validazione dei dati, il parsing, l'evidenziazione della sintassi e altro ancora.
Ad esempio, puoi verificare rapidamente se una string assomiglia a un indirizzo email:
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRegex.test("[email protected]")); // true
console.log(emailRegex.test("not-an-email")); // falseNota: questo è un pattern semplificato. Per la validazione in produzione, considera regole più rigide o librerie dedicate.
Dove viene usata la regex:
- Sviluppo web: validazione degli input dei form, parsing degli URL e ricerca nei contenuti.
- Analisi dei dati: estrazione di pattern specifici da grandi dataset.
- Modifica del testo: ricerca e sostituzione di testo in documenti o codebase.
- Linguaggi di programmazione: la maggior parte dei linguaggi moderni, incluso JavaScript, supporta la regex.
Creare un'espressione regolare
JavaScript offre due modi per creare una regex, e la differenza è importante nella pratica.
// 1. Literal syntax — compiled once when the script loads.
const re1 = /\d+/g;
// 2. Constructor — useful when the pattern is built from a variable.
const word = "cat";
const re2 = new RegExp(word + "s?", "i"); // matches "cat" or "cats", case-insensitive
console.log(re1 instanceof RegExp); // true
console.log(re2.source, re2.flags); // cats? iUsa la forma letterale per i pattern fissi — è più breve e il motore la compila in anticipo. Ricorri al costruttore RegExp quando il pattern è dinamico (ad esempio, costruito dall'input dell'utente). Ricorda che in una string devi raddoppiare il backslash: "\\d" in un costruttore equivale a \d in un letterale.
Come la regex si connette alle stringhe: i metodi principali
Un pattern è utile solo insieme a un metodo che lo esegue. Questi sono quelli che utilizzerai ogni giorno.
const text = "The year 2023 follows 2022.";
// test() → boolean: "does it match anywhere?"
console.log(/\d{4}/.test(text)); // true
// String.match() with /g → array of all matches
console.log(text.match(/\d{4}/g)); // [ '2023', '2022' ]
// String.replace() → returns a new string
console.log(text.replace(/\d{4}/g, "YEAR")); // The year YEAR follows YEAR.
// RegExp.exec() → one match at a time, with capture groups
console.log(/(\d{4})/.exec(text)[1]); // 2023
// String.matchAll() → iterator of full match objects (needs /g)
for (const m of text.matchAll(/(\d{4})/g)) {
console.log(m[0], "at index", m.index);
}
// 2023 at index 9
// 2022 at index 22Scegli il metodo in base all'obiettivo: test() per una verifica sì/no, match()/matchAll() per estrarre dati, e replace() per riscrivere il testo. La flag g (globale) è quella che trasforma "la prima corrispondenza" in "tutte le corrispondenze", quindi è essenziale per match, matchAll e le operazioni di sostituzione globale.
Leggere un pattern: i blocchi di base più comuni
La maggior parte dei pattern è assemblata da un piccolo vocabolario. Ecco un esempio funzionante che usa diversi elementi insieme:
const log = "2023-06-19 ERROR user=42 path=/login";
// \d digit \w word char \s whitespace
// . any char + 1 or more [] a set of chars
const match = log.match(/(\d{4}-\d{2}-\d{2})\s+(\w+)\s+user=(\d+)/);
console.log(match[1]); // 2023-06-19 (the date group)
console.log(match[2]); // ERROR (the level group)
console.log(match[3]); // 42 (the user id group)Ogni (...) è un gruppo di cattura il cui testo appare nell'array dei risultati. \d, \w e \s sono classi di caratteri; i quantificatori + e {4} indicano quante volte ripetere il token precedente. Combinandoli puoi estrarre dati strutturati da testo semplice.
Riferimento rapido: Flag e quantificatori
| Categoria | Simbolo/Flag | Descrizione |
|---|---|---|
| Flag | i | Corrispondenza senza distinzione tra maiuscole e minuscole |
g | Corrispondenza globale (trova tutte le corrispondenze) | |
m | Modalità multiriga (^ e $ corrispondono ai confini di riga) | |
s | Modalità dotall (. corrisponde ai caratteri di nuova riga). Richiede supporto ES2018+. | |
u | Modalità Unicode | |
y | Modalità sticky (corrisponde solo da lastIndex) | |
| Quantificatori | * | 0 o più volte |
+ | 1 o più volte | |
? | 0 o 1 volta | |
{n} | Esattamente n volte | |
{n,} | n o più volte | |
{n,m} | Tra n e m volte |
Errori comuni
Alcune sorprese colgono di sorpresa quasi tutti coloro che imparano la regex in JavaScript:
-
Una regex con
/gricorda dove si è fermata. Quando riutilizzi lo stesso oggettoRegExpcontest()oexec(), esso avanzalastIndextra le chiamate, quindi il secondotest()può restituirefalsesu una string che chiaramente corrisponde. Usa un letterale fresco ogni volta, oppure reimpostare.lastIndex = 0.const re = /a/g; const s = "a"; console.log(re.test(s)); // true console.log(re.test(s)); // false — lastIndex moved past the end -
I pattern dinamici devono fare l'escape dell'input dell'utente. Se costruisci una regex dal testo digitato dall'utente, caratteri come
.o(vengono trattati come speciali. Fai prima l'escape:const escape = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); const userInput = "a.b"; const re = new RegExp(escape(userInput)); console.log(re.test("axb")); // false — the dot is now literal console.log(re.test("a.b")); // true -
Greedy per impostazione predefinita.
.+cattura il più possibile; aggiungi?per renderlo lazy (.+?). Vedi Quantificatori greedy e lazy.
Percorso di apprendimento
Questa pagina è il punto di ingresso alla sezione regex del corso. Segui i capitoli seguenti nell'ordine indicato per una comprensione completa e pratica:
- Pattern e flag — costruzione dei pattern e come le flag (
i,g,m,s,u,y) cambiano la corrispondenza. - Classi di caratteri —
\d,\w,\se le loro negazioni. - Unicode: flag
ue classe\p{...}— gestione di testo multilingue ed emoji. - Ancore: inizio
^e fine$della string — corrispondenza ai confini. - Modalità multiriga delle ancore, flag
m— far corrispondere^e$a ogni riga. - Confine di parola
\b— corrispondenza di parole intere. - Escape dei caratteri speciali — usare
.,(,?in modo letterale. - Insiemi e intervalli
[...]— insiemi di caratteri personalizzati. - Quantificatori
+,*,?,{n}— specificare la ripetizione. - Quantificatori greedy e lazy — controllare quanta parte viene catturata.
- Gruppi di cattura — estrarre e nominare le parti di una corrispondenza.
- Backreference
\ne\k<name>— riutilizzare il testo catturato. - Alternanza (OR)
|— corrispondere a una di diverse opzioni. - Lookahead e lookbehind — asserzioni a larghezza zero.
- Backtracking catastrofico — diagnosticare ed evitare prestazioni patologiche.
- Flag sticky
y, ricerca in posizione — corrispondenza ancorata basata sulla posizione.
Per i metodi che eseguono questi pattern, consulta il capitolo sull'oggetto RegExp e i suoi metodi e quello sulle stringhe JavaScript.
Al termine di queste lezioni, sarai in grado di creare pattern regex efficaci per cercare, validare e trasformare il testo in JavaScript.