Le espressioni regolari sono dei pattern che forniscono strumenti molto potenti per la ricerca e la sostituzione di testo.
In JavaScript, queste sono disponibili utilizzando l’oggetto RegExp, oltre ad essere integrato negli oggetti di tipo stringa.
Espressioni regolari
Un’espressione regolare (regular expression, “regexp” o solo “reg”) è formata da una sequenza di caratteri (pattern) e da eventuali flag.
Esistono due tipi di sintassi per creare un oggetto di tipo “regular expression”.
La versione più lunga:
regexp = new RegExp("pattern", "flags");
…e la più corta, usando gli slash "/"
:
regexp = /pattern/; // senza flag
regexp = /pattern/gmi; // con le flag g,m e i (da approfondire a breve)
Gli slash "/"
comunicano a JavaScript che stiamo creando un’espressione regolare. Hanno lo stesso ruolo delle virgolette per le stringhe.
Gli slash "/"
vengono usati quando conosciamo l’espressione regolare e possiamo includerla staticamente nel codice, questa è la situazione più comune. Invece new RegExp
viene usato quando dobbiamo creare un’espressione regolare al volo partendo da una stringa generata dinamicamente, come nell’esempio:
let tag = prompt("What tag do you want to find?", "h2");
let regexp = new RegExp(`<${tag}>`); // equivale a /<h2>/ se nel prompt sopra avete risposto "h2"
Flags
Le espressioni regolari possono avere delle flag che ne influenzano la ricerca.
In JavaScript ne abbiamo a disposizione 6:
i
- Con questo flag, la ricerca è case-insensitive: non c’è alcuna differenza tra
A
eda
(vedi gli esempi sotto). g
- Con questo flag, la ricerca ritornerà tutte le occorrenze, senza questo flag, ritornerebbe solo la prima occorrenza.
Quindi se cerchiamo la sequenza /love/
avremo lo stesso risultato che otteniamo cercando "love"
.
s
- Abilita la modalità “dotall”, che consente di utilizzare
.
per cercare i caratteri nuova riga\n
(studiati nel capitolo Classi di caratteri). u
- Abilita il supporto completo a Unicode. Questo flag consente di processare correttamente le coppie di caratteri surrogati. Visti in maniera più approfondita nel capitolo Unicode: flag "u".
y
- Abilita la modalità “Sticky”: la quale ricerca ad un’esatta posizione nel testo (studiata in maggior dettaglio nel capitolo Sticky flag "y", ricerca della posizione)
Da qui in avanti, lo schema di colori è il seguente:
- espressione regolare –
rosso
- stringa (all’interno della quale cerchiamo) –
blu
- risultato –
verde
Searching: str.match
Come detto in precedenza, le espressioni regolari sono integrate nei metodi delle stringhe.
Il metodo str.match(regexp)
trova tutte le occorrenze di regexp
nella stringa str
.
Possiede 3 diverse modalità:
-
Se l’espressione regolare ha la flag
g
, questa ritornerà un array con tutti i match:let str = "We will, we will rock you"; alert( str.match(/we/gi) ); // We,we (un array di 2 sotto stringhe contenente i match)
Da notare che entrambi
We
ewe
sono stati trovati, poiché il flagi
rende l’espressione regolare case-insensitive. -
Se non viene fornita questa flag, allora la ricerca ritornerà solamente il primo match sotto forma di array, con con il match completo all’indice
0
ed alcuni ulteriori dettagli:let str = "We will, we will rock you"; let result = str.match(/we/i); // senza la flag g alert( result[0] ); // We (primo match) alert( result.length ); // 1 // Details: alert( result.index ); // 0 (position del match) alert( result.input ); // We will, we will rock you (stringa originale)
L’array potrebbe avere ulteriori indici, oltre allo
0
se una parte dell’espressione regolare è racchiusa tra parentesi. Lo studieremo nel dettaglio nel capitolo I gruppi di acquisizione (capturing group). -
E infine, se non si ha alcun match, viene ritornato
null
(non ha importanza se c’è il flagg
o no).Questa sfumatura è molto importante. Se non si ottiene alcun match, non riceveremo un’array vuoto, ma
null
. Dimenticarsene potrebbe portare a diversi errori, ad esempio:let matches = "JavaScript".match(/HTML/); // = null if (!matches.length) { // Error: Cannot read property 'length' of null alert("Error in the line above"); }
Se invece preferiamo che il risultato sia sempre sotto forma di array, possiamo riscriverla in questo modo:
let matches = "JavaScript".match(/HTML/) || []; if (!matches.length) { alert("No matches"); // ora funziona correttamente }
Sostituzioni: str.replace
Il metodo str.replace(regexp, replacement)
sostituisce i match trovati con l’utilizzo di regexp
nella stringa str
con replacement
(tutti i match nel caso ci sia la flag g
, altrimenti, solamente il primo).
Ad esempio:
// senza la flag g
alert( "We will, we will".replace(/we/i, "I") ); // I will, we will
// con la flag g
alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will
Il secondo argomento è la stringa di replacement
(quella che andrà a sostituire i match). Possiamo utilizzare combinazioni di caratteri speciali per inserire “frammenti” del match:
Symbols | Azione nella stringa di sostituzione |
---|---|
$& |
inserisce l’intero match |
$` |
inserisce una porzione della stringa prima del match |
$' |
inserisce una parte della stringa dopo il match |
$n |
se n è una cifra numerica 1-2, allora inserisce il contenuto dell’n-esima parentesi, più nel dettaglio nel capitolo I gruppi di acquisizione (capturing group) |
$<name> |
inserisce il contenuto delle parentesi con il name fornito, maggiori dettagli nel capitolo I gruppi di acquisizione (capturing group) |
$$ |
inserisce il carattere $ |
Un esempio con $&
:
alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript
Testing: regexp.test
Il metodo regexp.test(str)
cerca almeno un’occorrenza, se la trova ritorna true
, altrimenti false
.
let str = "I love JavaScript";
let regexp = /LOVE/i;
alert( regexp.test(str) ); // true
Più avanti nel capitolo studieremo ulteriori espressioni regolari, vedremo diversi esempi, e altri metodi.
Puoi trovare le informazioni complete riguardo i metodi nell’articolo Metodi di RegExp e String.
Riepilogo
- Un’espressione regolare è formata da una sequenza e eventualmente da alcune flag:
g
,i
,m
,u
,s
,y
. - Senza flag e simboli speciali che studieremo in seguito, cercare con una regexp è lo stesso di cercare con una sottostringa.
- Il metodo
str.search(regexp)
restituisce l’indice dove viene trovata la corrispondenza, oppure-1
se non ci sono corrispondenze. Nel prossimo capitolo vedremo altri metodi. - Il metodo
str.replace(regexp, replacement)
sostituisce tutte le occorrenze trovate tramite laregexp
conreplacement
: le sostituirà tutte se la flagg
è attiva, altrimenti sostituirà solamente la prima. - Il metodo
regexp.test(str)
ritornatrue
se trova almeno un match,false
altrimenti.