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:
JavaScript
var re = new RegExp("^http[s]?:\/\/", "ig");
per poi testare una stringa con il metodo test():
JavaScript
re.test("https://www.sgart.it")
// true
ottengo correttamente la risposta true.
Ma se la rieseguo... ottengo false:
JavaScript
// 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.
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
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:
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
L'espressione può essere scritta anche con un altra notazione:
JavaScript
var re = /^http[s]?:\/\//i;
il comportamento è identico.
Potrebbe interessarti anche: