Può capitare di ritrovarsi con "
strani" risultati durante l'uso del metodo
test() dell'oggetto
RegExp in
JavaScript.
Ad esempio se vogliamo verificare se una stringa inizia con
http:// o
https:// possiamo usare un espressione come questa:
var re = new RegExp("^http[s]?:\/\/", "ig");
per poi testare una stringa con il metodo
test():
re.test("https://www.sgart.it")
// true
ottengo correttamente la risposta
true.
Ma se la rieseguo... ottengo
false:
// riuso l'oggetto creato
re.test("https://www.sgart.it")
// false
Questo comportamento è legato al modificatore
g (global) che esegue il test in funzione della proprietà
re.lastIndex.
All'inizio,
re.lastIndex è impostato a
0 e il risultato è correttamente
true. Però il test andato a buon fine, comporta lo spostamento in avanti della proprietà
lastIndex, nell'esempio al valore
7 (la fine del
match trovato).
Al successivo uso di
test(), il confronto parte dal valore di
lastIndex, ovvero da
www.sgart.it, che ovviamente non soddisfa la
regular expression e quindi ritorna
false.
var re = new RegExp("^http[s]?:\/\/", "ig");
// undefined
re.lastIndex
// 0
re.test("http://www.sgart.it")
// true
re.lastIndex
// 7
re.test("http://www.sgart.it")
// false
re.lastIndex
// 0
l'alternanza
true/false si ripete ad ogni uso di
test().
Ovviemente il comportamento è corretto ma non risulta molto intuitivo.
Per risolvere il problema, è non avere un comportamento "imprevedibile", non va usato il modificatore
g (global).
Questo esempio ritorna sempre un risultato prevedibile:
var re = new RegExp("^http[s]?:\/\/", "i");
// undefined
re.lastIndex
// 0
re.test("http://www.sgart.it")
// true
re.lastIndex
// 0
re.test("http://www.sgart.it")
// true
re.lastIndex
// 0
L'espressione può essere scritta anche con un altra notazione:
var re = /^http[s]?:\/\//i;
il comportamento è identico.