2012-01-18 10 views

Respuesta

24

Para solucionar el problema, puede quitar la bandera g o restablecer lastIndex como en

var reg = /a/g; 
console.log(reg.test("a")); 
reg.lastIndex = 0; 
console.log(reg.test("a")); 

El problema surge porque test se basa en exec el que busca más partidos después de la primera si se aprueba la misma cadena y la bandera g está presente.

15.10.6.3RegExp.prototype.test(string) # Ⓣ Ⓡ

se toman las siguientes medidas:

  1. Vamos partido ser el resultado de evaluar el algoritmo de RegExp.prototype.exec (15.10.6.2) sobre este objeto RegExp usando cadena como argumento.
  2. Si coincide no es null, entonces devuelva true; else return false.

La parte clave de exec es el paso 6 de 15.10.6.2:

6. Vamos mundial sea el resultado de llamar al [[Obtener]] método interno de I con el argumento "global".
7. Si global es falsa, entonces que i = 0.

Cuando i no se restablece a 0, entonces exec (y por lo tanto test) no empezar a buscar en el principio de la cadena.

Esto es útil para exec porque se puede bucle para manejar cada partido:

var myRegex = /o/g; 
var myString = "fooo"; 
for (var match; match = myRegex.exec(myString);) { 
    alert(match + " at " + myRegex.lastIndex); 
} 

pero obviamente no es tan útil para test.

+0

Lo que significa que debo configurar lastIndex en 0, ¿no? – NStal

+0

+1 buena explicación, no lo sabía. –

+0

@NStal, Sí, estableciendo 'lastIndex' en 0 antes de que la prueba resuelva el problema. –

2

Por lo general, se elige una prueba para verificar si algún patrón coincide en absoluto, pero la bandera global le permite recorrer una cadena para contar las coincidencias o, como exec, hacer algo con cada lastIndex. Otro uso es establecer el último índice del rx usted mismo antes de que se realice la prueba, para ignorar las coincidencias antes de algún índice de caracteres.

var count=0, rx=/\s+/g, rx.lastIndex=100; 
while(rx.test(string))count++; 
Cuestiones relacionadas