Errore con RegExp.test(string) in JavaScript
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:
per poi testare una stringa con il metodo test():
ottengo correttamente la risposta true.
Ma se la rieseguo... ottengo 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.
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:
L'espressione può essere scritta anche con un altra notazione:
il comportamento è identico.
Ad esempio se vogliamo verificare se una stringa inizia con http:// o https:// possiamo usare un espressione come questa:
JavaScript
var re = new RegExp("^http[s]?:\/\/", "ig");
JavaScript
re.test("https://www.sgart.it")
// true
Ma se la rieseguo... ottengo false:
JavaScript
// riuso l'oggetto creato
re.test("https://www.sgart.it")
// false
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.
JavaScript
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
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:
JavaScript
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
JavaScript
var re = /^http[s]?:\/\//i;