Se si ha una stringa come la seguente: +7(903)-123-45-67 e si vogliono trovare tutti i numeri che contiene ma, diversamente da prima, non siamo interessati alle singole cifre bensì agli interi numeri: 7, 903, 123, 45, 67.
Se definisce numero un sequenza di una o più cifre \d, per marcare quanti ne servono si deve aggiungere in coda un quantificatore.
Quantità {n}
Il quantificatore più semplice è un numero tra parentesi graffe {n}.
Un quantificatore si appende a un carattere (o a una classe di caratteri [...] un set, ecc…) specificando quante volte questo debba essere ripetuto.
Si riportano alcune forme avanzate, eccone alcuni esempi:
- Il conteggio esatto:
{5} -
\d{5}denota esattamente 5 cifre, identico a\d\d\d\d\d.Nell’esempio sottostante si cerca un numero a 5 cifre:
alert( "Ho 12345 anni".match(/\d{5}/) ); // "12345"Si può aggiungere
\bper escludere i numeri più lunghi:\b\d{5}\b. - L’intervallo:
{3,5}, trova da 3 a 5 ripetizioni. -
Per trovare i numeri da 3 a 5 cifre si possono mettere i limiti tra parentesi graffe:
\d{3,5}alert( "Non ho 12 anni 12, ma 1234".match(/\d{3,5}/) ); // "1234"Si può tralasciare il limite superiore.
In questo caso la regexp
\d{3,}cercherà successioni di cifre lunghe3o più:alert( "Non ho 12 anni, ma 345678".match(/\d{3,}/) ); // "345678"
Torniamo alla stringa: +7(903)-123-45-67.
Un numero è una sequenza di una o più cifre in successione, dunque l’espressione regolare sarà \d{1,}:
let str = "+7(903)-123-45-67";
let numeri = str.match(/\d{1,}/g);
alert(numeri); // 7,903,123,45,67
Abbreviazioni
Sono presenti abbreviazioni per i quantificatori di uso più comune:
+-
Significa “uno o più”, identico a
{1,}.Ad esempio,
\d+cerca i numeri:let str = "+7(903)-123-45-67"; alert( str.match(/\d+/g) ); // 7,903,123,45,67 ?-
Significa “zero o uno” identico a
{0,1}. In altri termini rende il simbolo opzionale.Ad esempio, il pattern
ou?rcercaoseguito opzionalmente dau, quindi dar.Dunque,
colou?rtrova siacolorchecolour:let str = "In Inglese \"colore\" si scrive sia \"color\" che \"colour\"?"; alert( str.match(/colou?r/g) ); // color, colour *-
Significa “zero o più”, lo stesso che
{0,}. Significa che il carattere può esserci, essere ripetuto o mancare.Ad esempio,
\d0*cerca una cifra seguita da un numero arbitrario di zeri:alert( "100 10 1".match(/\d0*/g) ); // 100, 10, 1Confronto con
'+'(uno o più):alert( "100 10 1".match(/\d0+/g) ); // 100, 10 // 1 non compare, poiché 0+ richiede almeno uno 0
Altri esempi
I quantificatori si usano spesso; essi costituiscono i blocchi principali per espressioni regolari complesse, si riportano in seguito altri esempi.
- Regexp “frazione decimale” (un numero con la virgola):
\d+,\d+ -
In funzione:
alert( "0 1 12,345 7890".match(/\d+,\d+/g) ); // 12,345 - Regexp “Apertura di un tag HTML senza attributi” come, ad esempio,
<span>oppure<p>:/<[a-z]+>/i -
In funzione:
alert( "<body> ... </body>".match(/<[a-z]+>/gi) ); // <body>Cerchiamo il carattere
'<'seguito da una o più lettere latine one or more Latin letters, quindi'>'. - Regexp “Apertura di un tag HTML senza attributi” (migliorato):
/<[a-z][a-z0-9]*>/i -
Espressione regolare migliore: secondo lo standard, il nome di un tag HTML può avere cifre in qualsiasi posizione tranne la prima
<h1>.alert( "<h1>Hi!</h1>".match(/<[a-z][a-z0-9]*>/gi) ); // <h1> - Regexp “Apertura o chiusura di un tag HTML senza attributi”:
/<\/?[a-z][a-z0-9]*>/i -
Aggiungiamo una slash opzionale
/?prima del nome tag, dobbiamo farne l’escape altrimenti JavaScript penserebbe che sia la fine del pattern.
We added an optional slash /? near the beginning of the pattern. Had to escape it with a backslash, otherwise JavaScript would think it is the pattern end.
alert( "<h1>Hi!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>
Possiamo vederne una regola comune in questo esempio: più l’espressione regolare è precisa – più è lunga e complicata.
Ad esempio, per i tag HTML è possibile usare un’espressione regolare più semplice: <\w+>.
…Ma poiché \w intercetta qualsiasi lettera dell’alfabeto latino e il carattere '_', la regexp intercetta anche dei non-tag, come <_>. Dunque è molto più semplice del pattern <[a-z][a-z0-9]*>, ma anche meno affidabile.
Basta accontentarsi di <\w+> o è necessario <[a-z][a-z0-9]*>?
La risposta è che nella vita reale entrambi sono accettabili; dipende però dal bilanciamento tra l’avere molte corrispondenze “extra” da filtrare in altri modi rispetto all’avere un’espressione regolare più complessa.
Commenti
<code>, per molte righe – includile nel tag<pre>, per più di 10 righe – utilizza una sandbox (plnkr, jsbin, codepen…)