Compte tenu de ce code:
var reg = /a/g; console.log(reg.test("a")); console.log(reg.test("a"));
Je reçois ce résultat:
true false
Je ne sais pas comment cela pourrait se produire. J'ai testé à la fois dans Node.js (v8) et Firefox.
Pour contourner le problème, vous pouvez supprimer le drapeau g
ou réinitialiser lastIndex
comme dans
var reg = /a/g; console.log(reg.test("a")); reg.lastIndex = 0; console.log(reg.test("a"));
Le problème se pose parce que le test
est basé sur exec
qui recherche d'autres correspondances après le premier s'il a passé la même chaîne et que le drapeau g
est présent.
15.10.6.3
RegExp.prototype.test(string)
# Ⓣ ⓇLes étapes suivantes sont prises:
- Laissez correspondre le résultat de l'évaluation de l'
RegExp.prototype.exec
(15.10.6.2) sur cet objetRegExp
utilisant la chaîne comme argument.- Si la correspondance n'est pas
null
, retourneztrue
; Sinon retournerfalse
.
La partie clé de exec
est l'étape 6 de 15.10.6.2 :
6. Laissez global être le résultat d'appeler la méthode interne [[Get]] de R avec l'argument "global".
7. Si global est faux, laissez i = 0.
Lorsque i
n'est pas réinitialisé à 0, alors exec
(et donc test
) ne commence pas à regarder le début de la chaîne.
Ceci est utile pour exec
car vous pouvez faire une boucle pour gérer chaque correspondance:
var myRegex = /o/g; var myString = "fooo"; for (var match; match = myRegex.exec(myString);) { alert(match + " at " + myRegex.lastIndex); }
Mais évidemment ce n'est pas si utile pour le test
.
Habituellement, un test est choisi pour vérifier si un certain motif correspond au tout, mais l'indicateur global vous permet de passer une chaîne à compter les correspondances ou, comme exec, faire quelque chose avec chaque lastIndex. Une autre utilisation est de définir le dernierIndex du rx vous-même avant que le test ne soit effectué, d'ignorer les correspondances avant un indice de personnage.
var count=0, rx=/\s+/g, rx.lastIndex=100; while(rx.test(string))count++;