2012-04-19 14 views
5

Duplicar posible:
Javascript regex returning true.. then false.. then true.. etcBug con RegExp en JavaScript al hacer la búsqueda global

En primer lugar, disculpas por mi mala Inglés.

estoy tratando de probar cadena para que coincida con el patrón, por lo que ha escrito esto:

var str = 'test'; 
var pattern = new RegExp('te', 'gi'); // yes, I know that simple 'i' will be good for this 

Pero tengo resultados inesperados:

>>> pattern.test(str) 
true 
>>> pattern.test(str) 
false 
>>> pattern.test(str) 
true 

¿Alguien puede explicar esto?

Respuesta

10

La razón de este comportamiento es que RegEx no tiene estado. Su segundo test continuará buscando la siguiente coincidencia en la cadena e informará que no encuentra más. Otras búsquedas se inicia desde el principio, como lastIndex se restablece cuando no se encuentra una coincidencia:

var pattern = /te/gi; 

pattern.test('test'); 
>> true 
pattern.lastIndex; 
>> 2 

pattern.test('test'); 
>> false 
pattern.lastIndex; 
>> 0 

Se dará cuenta de cómo esto cambia cuando hay dos partidos, por ejemplo:

var pattern = /t/gi; 

pattern.test('test'); 
>> true 
pattern.lastIndex; 
>> 1 

pattern.test('test'); 
>> true 
pattern.lastIndex; 
>> 4 

pattern.test('test'); 
>> false 
pattern.lastIndex; 
>> 0 
2

supongo que se encontró con este problema: https://bugzilla.mozilla.org/show_bug.cgi?id=237111

Extracción del parámetro g resuelve el problema. Básicamente es debido a la propiedad lastindex que recuerda el último valor cada vez que se ejecute test() método

+0

¡Gracias por tu respuesta! Sí, ahora que eliminar 'g' resuelve este problema. Pero este error también aparece en Chrome ... –

+0

No es un error. 'test' y' exec' están diseñados para hacer eso. Ahora déjame ir a buscar a la víctima ... – zzzzBov

+0

No diría que es un error. es cómo se implementan las expresiones regulares. De hecho, es un problema para OP – fcalderan

1

citar el MDN Docs (el énfasis es mío):

Cuando se desea saber si un patrón se encuentra en una utilización cuerdas el método de prueba (similar al método String.search); para más información (pero ejecución más lenta) use el método exec (similar al método String.match). Al igual que con exec (o en combinación con él), la prueba llamada varias veces en la misma instancia de expresión regular global avanzará más allá de la coincidencia anterior.

0

Este es el comportamiento previsto del RegExp.test(str) method. La instancia de expresiones regulares (patrón) almacena el estado que se puede ver en la propiedad lastIndex; cada vez que llamas a "prueba" actualiza ese valor y las siguientes llamadas con el mismo argumento pueden o no dar el mismo resultado:

var str="test", pattern=new RegExp("te", "gi"); 
pattern.lastIndex; // => 0, since it hasn't found any matches yet. 
pattern.test(str); // => true, since it matches at position "0". 
pattern.lastIndex; // => 2, since the last match ended at position "1". 
pattern.test(str); // => false, since there is no match after position "2".