Come utilizzare le espressioni regolari in JavaScript?

Dopo aver esaminato le basi teoriche e la sintassi delle espressioni regolari, è importante sapere come utilizzare queste conoscenze in ambito produttivo. Infatti, sebbene le regole siano comuni, ogni linguaggio di programmazione utilizza delle routine proprie: in questo articolo presenteremo l’implementazione delle regex in JavaScript ed i metodi principali associati alla loro gestione.

Le espressioni regolari in JavaScript vengono create come semplici stringhe, delimitate da forward slash, seguiti da alcuni caratteri speciali, detti flags, che modificano la metodologia di ricerca. Potremmo avere quindi una variabile (o più precisamente un letterale):

var regex = /modelloRegex/flags;

Il modello può essere una qualsiasi espressione regolare, mentre per i flag possono essere utilizzati i tre caratteri g, i o m:

  • g: il modello viene cercato in tutta la stringa, invece di fermarsi dopo la prima occorrenza trovata.
  • i: la ricerca non tiene conto della differenza di caratteri maiuscoli/minuscoli.
  • m: la ricerca viene effettuata anche dopo il termine della prima riga di testo.

Un primo semplice esempio di espressione regolare potrebbe essere quello per la ricerca di una stringa:

var regex = /Your Inspiration Web/i;

Cerca nell’ipotetico testo la stringa “Your Inspiration Web”, senza tener conto di eventuali differenze tra maiuscole e minuscole. Oppure potremmo riutilizzare l’espressione regolare utilizzata per verificare una data:

//cerca una data
var regex = "/\d{2}-\d{2}-\d{4}/g";

Nell’implementazione delle espressioni regolari in JavaScript ci sono, però, alcune variazioni: quella del metacarattere ‘punto’, ovverosia “ogni carattere”, è forse la più rilevante. Infatti è il carattere ‘a capo’ non viene corrisposto quando è settato il flag m . Per ovviare a questa mancanza si può utilizzare l’insieme di una classe di caratteri e della sua negazione, spesso nella forma “[\s\S]”. Ma cosa significa? Controllando la tabella del precedente articolo puoi notare che la classe ‘\s’ si riferisce a “tutti i caratteri di spaziatura”. Aggiungendo nell’insieme ‘\S’ che sta per “tutti i caratteri che non sono spazi” in pratica stiamo dicendo “prendi gli spazi e tutti i caratteri che non sono spazi”; in poche parole “tutti i caratteri”.

Quella del punto è l’unica assenza degna di nota per un uso ‘normale’ delle regex in Javascript (ci sono altre differenze). La domanda da porsi adesso è: come testare le nostre espressioni regolari in JavaScript?

L’oggetto RegExp

In realtà in JavaScript tutte le espressioni regolari (anche quelle di esempio realizzate sopra) sono un’istanza dell’oggetto RegExp. Non è rilevante a questo scopo conoscere la programmazione ad oggetti: basta solo tenere a mente che un oggetto è una struttura (come un array) che possiede delle proprietà (gli attributi) e dei comportamenti (i metodi). I metodi e gli attributi sono propri dell’oggetto a cui si riferiscono e la sintassi per richiamarli è la seguente:

/* questa è denominata "dot notation", per l'uso del punto */
oggetto.attributo;

oggetto.metodo(parametri);

Su un oggetto di tipo RegExp i metodi rilevanti sono due: test ed exec. Il primo esegue un test, appunto, di un’espressione regolare su una stringa, verificando che in essa vi sia almeno una corrispondenza. Il secondo invece, restituisce le informazioni sull’eventuale occorrenza trovata nella stringa.

Per quanto riguarda gli attributi sono degni di nota lastIndex, che contiene la posizione del prossimo carattere da esaminare da parte della regex, e source, che contiene la stringa dell’espressione regolare vera e propria.

Prima di provare queste funzioni, creiamo una pagina html per i test:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"https://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="https://www.w3.org/1999/xhtml" xml:lang="it" lang="it">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>Espressioni regolari in JavaScript | Your Inspiration Web</title>
</head>
<body>
<h1>Pagina di prova per le espressioni regolari</h1>

<script type="text/javascript">
/* Qui andranno le nostre prove */
</script>
</body>
</html>

Scriveremo il nostro codice JavaScript all’interno del tag “script” in basso alla pagina.

Il metodo test()

Il metodo test accetta come parametro una stringa a cui applicare l’espressione regolare, e ha come valore di ritorno un booleano: true, se la stringa corrisponde all’espressione regolare, false altrimenti.

Come primo esempio per il metodo test, cerchiamo in una stringa le corrispondenze della regex /CaSa/i:

/* Crea l'espressione regolare non distinguendo tra maiuscole e minuscole*/
var regex = /CaSa/i;
/* Imposta la stringa su cui cercare */
var str = "Casa dolce casa"
/* se vi è una corrispondenza, visualizza un messaggio */
if( regex.test(str) ){
    /* azione da eseguire se vi è una corrispondenza */
    alert("Corrispondenza Trovata");
}

Analizziamo passo per passo questa porzione di codice. Abbiamo:

  1. creato la nostra espressione regolare, in questo caso una semplice stringa, impostando il flag case-insensitive;
  2. inizializzato la stringa che fungerà da testo di ricerca, nella realtà questa sarà rappresentata dai valori di un form, oppure dal testo preso da una pagina web;
  3. utilizzato il metodo test nel suo ambiente più congeniale, un costrutto if, se vi è una corrispondenza esegue l’azione relativa, altrimenti procede con il codice successivo.

Nota come, dopo aver creato l’espressione regolare, abbiamo richiamato il metodo “test” utilizzando la dot-notation: richiamare “test” senza anteporre il nome dell’oggetto risulterà un errore.

Il metodo exec

Sfruttando la stessa espressione regolare e la stessa stringa, vediamo come lavora il metodo “exec”. Quest’ultimo prende come parametro una stringa a cui applicare la regex, ma ha come valore di ritorno un array contenente l’occorrenza trovata. Tale array possiede un attributo, index che contiene la posizione dell’occorrenza all’interno della stringa (il numero del carattere dall’inizio della stringa, più precisamente).

Vediamo un semplice esempio:

/* Crea l'espressione regolare */
var regex = /CaSa/i;
/* Imposta la stringa su cui cercare */
var str = "Oh, Casa dolce casa"
var risultato = regex.exec(str);

/* stampa la stringa trovata come corrispondenza */
alert(risultato[0]); //Casa
/* stampa la posizione nella stringa in cui è stata
 * trovata una corrispondenza: parte da 0 */
alert(risultato.index); //4

La creazione dell’espressione regolare e della stringa è identica a quella precedente. La prima differenza è il valore di ritorno del metodo, che viene salvato nella variabile “risultato”. Questa variabile è un array contenente nella prima posizione l’occorrenza dell’espressione regolare trovata nella stringa, mentre nell’attributo “index” è memorizzata la posizione dell’occorrenza della stringa.

Una cosa interessante da notare è che, ripetendo l’esecuzione del metodo “exec” senza specificare il flag “g”, si ottiene sempre e solo la prima occorrenza:

/* Crea l'espressione regolare */
var regex = /CaSa/i;
/* Imposta la stringa su cui cercare */
var str = "Oh, Casa dolce casa"

var risultato = regex.exec(str);
/* stampa la stringa trovata come corrispondenza */
alert(risultato[0]); //Casa
/* stampa la posizione nella stringa in cui è stata
 * trovata una corrispondenza: parte da 0 */
alert(risultato.index); //4

risultato = regex.exec(str);
risultato = regex.exec(str);
risultato = regex.exec(str);
risultato = regex.exec(str);

/* la stringa è sempre la stessa */
alert(risultato[0]); //Casa
/* ed è sempre la prima, quella in posizione 4 */
alert(risultato.index); //4

Per consentire a JavaScript di cercare le occorrenze successive della regex si deve, come accennato, utilizzare il flag “global” nella definizione dell’espressione regolare:

/* Crea l'espressione regolare: ho specificato il flag g */
var regex = /CaSa/ig;
/* Imposta la stringa su cui cercare */
var str = "Oh, Casa dolce casa"

var risultato = regex.exec(str);
/* stampa la stringa trovata come corrispondenza */
alert(risultato[0]); //Casa
/* stampa la posizione nella stringa in cui è stata
 * trovata una corrispondenza: parte da 0 */
alert(risultato.index); //4

risultato = regex.exec(str);

/* la stringa  */
alert(risultato[0]); //Casa
/* stavolta è la seconda occorrenza, quella in posizione 15 */
alert(risultato.index); //15

Specificando il flag global informiamo JavaScript che deve continuare la ricerca nel testo (un po’ come la funzione “Trova successivo” degli editor di testo): quando non vi sono più occorrenze il metodo “exec” ritornerà il valore “NULL”, che dovremo gestire adeguatamente.

Considerazioni finali

Le espressioni regolari possono semplificare molto la gestione di un’applicazione web. Va detto però che il motore delle regex richiede una percentuale di CPU molto elevata, quindi è bene utilizzarle con accortenza, verificando che non ci siano altri modi più veloci per ottenere lo stesso risultato. Ad esempio, volendo cercare tutti le righe di una stringa che terminino per punto e virgola, si potrebbe essere tentati di utilizzare l’espressione regolare:

var regex = /;$/;

Questa semplice espressione regolare potrebbe impegnare il tuo browser per svariati secondi (anche minuti, in caso di testi molto lunghi): questo perché la ricerca non viene effettuata solo alla fine della stringa, bensì comincia dal primo carattere, esaminandone uno alla volta, fino alla fine, per poi dare il risultato. Ma come migliorare questa ricerca?

Le espressioni regolari sono utili quando non si hanno ipotesi sul testo: in questo caso, invece, noi vogliamo sapere solo se l’ultimo carattere è un punto e virgola. Perché allora non effettuare il test solo su quell’ultimo carattere?

var str = "Ciao a tutti;";
if( str.charAt(str.length - 1) == ";" )
    alert("La stringa termina con un punto e virgola");

Come hai visto ho utilizzato il metodo charAt per recuperare l’ultimo carattere e confrontarlo con la mia stringa di ricerca.

In generale dunque, quando si ha a che fare con la ricerca o la sostituzione di semplici stringhe, potrebbe essere una buona idea sperimentare prima con i metodi JavaScript che operano sulle stringhe (charAt, indexOf, slice, substr, substring), ed utilizzare le espressioni regolari se non si riesce a trovare una soluzione alternativa.

Tag: ,

L'autore

Appassionato di web design, si diletta a creare dei layout (X)HTML+CSS. È un maniaco del codice pulito e ordinato, il tipo di persona che vi ritrovate in casa a raddrizzarvi i quadri appesi alla parete. Ha deciso che diventerà un web designer con la “doppia vvu” maiuscola, e trascorre intere nottate sveglio per realizzare il suo sogno.

Sito web dell'autore | Altri articoli scritti da

Articoli correlati

Potresti essere interessato anche ai seguenti articoli:

5 commenti

Trackback e pingback

  1. Tweets that mention Come utilizzare le espressioni regolari in JavaScript? | Your Inspiration Web -- Topsy.com
    [...] This post was mentioned on Twitter by mtx_maurizio, Giustino Borzacchiel. Giustino Borzacchiel said: RT @YIW Come utilizzare le espressioni…
  2. Sicurezza e siti web: come trovare le cause di code injection, tecniche di validazione | Your Inspiration Web
    [...] con la sola sigla RE). L’argomento è stato trattato recentemente molto bene da JustB in questo articolo, a cui…