Alternanza è un termine usato nelle espressioni regolari che, in realtà, consiste in un semplice “OR”.
È indicata con un carattere di linea verticale |
.
Supponiamo di aver bisogno di trovare il nome di un linguaggio di programmazione: HTML, PHP, Java o JavaScript.
Ecco la regexp corrispondente: html|php|java(script)?
.
Ed ora un esempio d’uso:
let regexp = /html|php|css|java(script)?/gi;
let str = "First HTML appeared, then CSS, then JavaScript";
alert( str.match(regexp) ); // 'HTML', 'CSS', 'JavaScript'
Abbiamo già incontrato una funzionalità simile: le parentesi quadre. Essi permettono di scegliere tra più caratteri, ad esempio gr[ae]y
trova corrispondenza con gray
o grey
.
Le parentesi quadre consentono solo caratteri o classi di caratteri. L’alternanza consente qualsiasi espressione. Una regexp A|B|C
significa una delle espressioni A
, B
o C
.
Per esempio:
gr(a|e)y
ha lo stesso identico significato digr[ae]y
.gra|ey
significagra
oey
.
Per applicare l’alternanza ad una determinata parte di un pattern, dobbiamo racchiuderla tra parentesi:
I love HTML|CSS
trovaI love HTML
oCSS
.I love (HTML|CSS)
corrisponde aI love HTML
oI love CSS
.
Esempio: regexp per un orario
Negli articoli precedenti abbiamo effettuato un’esercitazione per realizzare una regexp e trovare un orario nel formato hh:mm
, ad esempio 12:00
. Un semplice \d\d:\d\d
, tuttavia, è troppo impreciso. Accetta un orario come 25:99
(poiché 99 minuti trova corrispondenza nel pattern, ma non è un orario valido).
Come possiamo migliorare questo pattern?
Possiamo cercare una corrispondenza più accurata. Per prima cosa, le ore:
- Se la prima cifra è
0
o1
, allora la cifra successiva può essere una qualsiasi:[01]\d
. - Diversamente, se la prima cifra è
2
, la successiva deve essere[0-3]
. - Non può esserci un altro carattere come prima cifra.
Possiamo scrivere entrambe le varianti in una regexp usando l’alternanza: [01]\d|2[0-3]
.
I minuti a seguire, essi devono essere compresi in un intervallo tra 00
e 59
. In un’espressione regolare ciò può essere reso come [0-5]\d
: la prima cifra 0-5
, quindi un numero qualsiasi.
Unendo le ore con i minuti otteniamo il pattern seguente: [01]\d|2[0-3]:[0-5]\d
.
Abbiamo quasi finito, ma c’è ancora un problema. L’alternanza |
al momento sembra avvenire tra [01]\d
e 2[0-3]:[0-5]\d
.
In altre parole: i minuti sono aggiunti al secondo termine dell’alternanza, ecco una rappresentazione più chiara:
[01]\d | 2[0-3]:[0-5]\d
Questo pattern cerca [01]\d
o 2[0-3]:[0-5]\d
.
Non è quello che vogliamo, l’alternanza dovrebbe riguardare solo le ore e consentire [01]\d
o 2[0-3]
. Correggiamo racchiudendo le ore tra parentesi: ([01]\d|2[0-3]):[0-5]\d
.
Ed ecco la soluzione definitiva:
let regexp = /([01]\d|2[0-3]):[0-5]\d/g;
alert("00:00 10:10 23:59 25:99 1:2".match(regexp)); // 00:00,10:10,23:59