Espressioni Regolari in JavaScript
Tags: javascript, regex, beginners, italian
Published: 2020-09-26 12:54:02

##Una breve introduzione al John Wick delle stringhe

**L**e espressioni regolari sono estremamente utilizzate e terribilmente confusionarie. Con l’esperienza, *prendendoci la mano*, rimarranno solo terribilmente confusionarie.

Le **RegExp** (termine tecnico) sanno essere ragazze veramente difficili da gestire: problema difficile da risolvere, difficoltà maggiori da controllare. Eppure talvolta si rilevano essere l’approccio più veloce, simpatico e soprattutto “pulito”. **Fare la loro conoscenza** — il che non significa risolvere ogni problemi con esse, anzi — **ci rende dei programmatori più vissuti**.
Non sono un’esclusiva di *Javascript*. Ciò non ci interessa, in questo articolo andremo a vedere proprio come utilizzarle con *il linguaggio web più in voga del momento*.

***

>*“Avete mai sentito l’arcaica espressione trovare un ago nel pagliaio? Sembra essere vecchia di 500 anni. Le espressioni regolari servono proprio a questo: tu indichi il pagliaio, che cosa trovare e loro lo trovano… a dir il vero fanno anche di più: separano l’ago dal pagliaio e, con esso, anche ogni singolo filo di paglia.”*

***

Signori, tra le mani abbiamo forse il tool più potente per processare e ispezionare stringhe di testo, caratteri alfanumerici, numeri, simboli e lettere senza senso. Sono tra i giocattoli dei grandi, e i piccoli sviluppatori — come me — non dovrebbero toccarli. Anche questo non sembra interessarci, andiamo a sporcarci le mani!

Le espressioni regolari, come quasi ogni cosa in JS, sono di tipo *Object* e possono essere richiamate in due modi: usando il costruttore *RegExp*; oppure servendoci dei slash di apertura e di chiusura:

```
let xyz= new RegExp(“xyz”);
let xyz = /xyz/;
```
L’uno o l’altro caso significa esclusivamente: *questa variabile xyz è un’espressione regolare ‘xyz’*. **Quindi una lettera x seguita da una y a suo volta seguita da una z**. Niente più, niente meno. Se andassimo ad aprire la console del nostro browser preferito e scrivessimo:
`console.log(/xyz/.test(“Che sciocchezza le espressioni regolari”));`
scopriremo che il risultato che ne verrà fuori sarà ineluttabilmente *False*.

Possiamo “risolvere il problema” studiando un po di più, o cambiando la stringa: *le espressioni regolari non sono affatto facili, dice Mr. xyz* — provate su — la nuova stringa passata come parametro della funzione test, prevede la presenza della nostra espressione ricercata, appunto *xyz*, sarà costretta a restituire un bel *True*.

***

**test** è il metodo più comune: **accetta una frase come parametro e restituisce un tipo Boolean**. Se la stringa inserita è presente nella nostra frase restituisce un altro bel *True*.

***

>Per ostacolare ancor più la comprensione, con “stringa” mi riferisco all'espressione regolare e con “frase” alla stringa nella quale andremo a effettuare la ricerca.

***

```
/iron/.test(“Guarda c’è ironman!”));
True
```

Ma metodi per stringhe *indexOf* e *includes* svolgono praticamente lo stesso compito di questo metodo per le espressioni regolari, *test*. Ma fidatevi di Mr. xyz, e portate un po di pazienza: di fatto, per compiti tanto semplici, non si ricorre alle regexp. Le cose cambiano invece quando **dobbiamo cercare** un insieme di caratteri alfanumerici non ben definiti, seguiti magari da **strani simboli alieni**… Vediamo qualche esempio.

```
/\D[0–5][6–9]\D/.test(“Ho appena compiuto 27 anni”);
True
```

La seguente espressione si può leggere in questo modo: **dentro la frase “Ho appena compiuto 27 anni” è presente l’espressione \D[0–5][6–9]\D**:
```
\D sta per “qualsiasi carattere che non sia un numero
[0–4] sta per “qualsiasi numero compreso tra 0 e 4, non ripetuto
[5–9] stessa cosa per sopra ma tra 5 e 9
\D sta nuovamente per “qualsiasi carattere che non sia un numero”
```

Analizzando nuovamente con comprendonio la nostra frase vedremo adesso che **ho appena compiuto** è un insieme di caratteri alfabetici e nessun numero, e che quindi rispetta la definizione \D;
**27** sono due numeri, precisamente il 2 e il 7, non ripetuti, ove il primo è compreso tra 0–4 e il secondo è compreso tra 5–9;
infine **anni** sono tutti caratteri alfabetici e nessun numero, rispetta anch'esso \D.

***

>*Da notare come la **built-in-shortcut** \D accetta più di un carattere o la ripetizione delle stesso o ancora la presenza di uno spazio o di qualsiasi altra cosa che non sia un numero. Mentre la scorciatoia tra parentesi quadre, che abbiamo adottato per la gestione dei numeri interi da 0 a 4, prevede un solo numero, per l’appunto, compreso tra 0 e 4, inclusi.*

***

```
Lista built-in-shortcut:
\d   Solo numeri
\w   Sia numeri che caratteri alfabetici
\s   Qualsiasi spazio vuoto, tabulazione, linea a capo, et similia
\D   Solo caratteri alfabetici
\W   Solo simboli
\S   Qualsiasi elemento eccezion fatta per gli spazi vuoti, tab, et
     similia
.    Qualsiasi carattere, numero, simbolo e spazio, eccezion fatta
     per il ritorno a capo
```

Data la tabella sopra, e la breve introduzione all'uso delle parentesi quadre, proviamo ad analizzare un esempio pratico, talvolta anche utile, ma al momento… cosa?!?:
`/^[A-Z]{6}\d{2}\D\d{2}\D\d{3}\D$/`

L’espressione soprastante, rullo di tamburi, va a verificare se la frase inserita è un codice fiscale valido. Capisco che ci sono simboli sconosciuti che ancora non sono stati trattati e certamente destano non poche perplessità. Ma **avete scelto voi di imparare a programmare**, tenetelo a mente; **episodi come questo sono frequenti!**:

```
^       Identifica l’inizio dell’espressione
[A-Z]   Tutte le parole dalla A alla Z
{6}     Identifica il numero di volte che verrà ripetuto 
        l’elemento precedente (nel caso [A-Z])
\d      Identifica un numero (già visto)
{2}     Nuovamente identifica il numero di volte, in questo caso
        dell’elemento \d
\w      Identifica un carattere
...     e così via, fino a
$       che identifica la fine dell’espressione
```

Quindi proviamo a inserire il nostro codice fiscale sulla console e vediamo un po se per il nostro computer siamo tipi *True* o *False*.

***
>**test** non è l’unico metodo a disposizione per la gestione delle espressioni. Diamo una veloce occhiata anche al metodo **replace**, che sostituisce parti di una stringa, e al metodo **exec**, che ci restituisce l’indice di riferimento di una porzione di stringa.
***

Il metodo **replace**, come suggerisce il nome, **rimpiazza una porzione della nostra frase con un’altra**.
```“Ironman”.replace(“man”, “woman”);```

Mentre il metodo **exec restituisce** un oggetto contenente — tra l’altro — **l’indice di riferimento della porzione di stringa ricercata**.
```/\d/.exec(“uno è diverso da 1”);```

Concludiamo in bellezza con un bel sommario semplice e conciso, rubato direttamente da *Eloquent Javascript*:

```
/xyz/     La sequenza di caratteri ‘xyz’
/[xyz]/   Almeno uno tra ‘x’ o ‘y’ o ‘z’
/[^xyz]/  Qualunque carattere eccetto la sequenza 
          ‘xyz’
/[0–9]/   Qualunque numero compreso tra 0 e 9
/z+/      Una o più occorrenze del carattere ‘z’
/z*/      Zero o più occorrenze del carattere ‘z’
/z?/      Zero o una occorrenza del carattere ‘z’
/z{2,4}/  Da due a quattro occorrenza del carattere 
          ‘z’
/(xyz)/   Il gruppo della sequenza ‘xyz’
/x|y|z/   Almeno uno tra ‘x’ o ‘y’ o ‘z’
/\d/      Solo numeri
/\w/      Sia numeri che caratteri alfabetici
/\s/      Qualsiasi spazio vuoto, tabulazione, linea a 
          capo, et
          similia
/\D/      Solo caratteri alfabetici
/\W/      Solo simboli
/\S/      Qualsiasi elemento eccezion fatta per gli 
          spazi vuoti, tab, et similia
/./       Qualsiasi carattere, numero, simbolo e 
          spazio, eccezione il ritorno a capo
/^/       Inizio
/$/       Fine
```

***
##*A questo punto spero proprio di non aver esagerato, e vi auguro di trovare tutti gli aghi in tutti i vostri pagliai!*
**Buona programmazione!**