2012-02-14 8 views
5

Parece que estoy obteniendo un resultado constantemente extraño al probar mi expresión regular en JavaScript.Javascript Regex debería pasar .test() pero parece fallar, ¿por qué?

Aquí es mi violín: http://jsfiddle.net/s5fYf/15/

Esto está tomado de un proyecto web que estoy construyendo. Paso una serie de objetos de validación en mi función de validación que los recorre iterativamente, validando cada regla con el valor. Si uno es falso, debe detener el ciclo y devolver un objeto de retorno que recoge un mensaje y cssClass de la regla fallida.

El problema es que el método de validación parece devolver falso incluso si pasa la prueba de expresiones regulares, ¡lo que debería ser imposible! Entonces siento que me falta algo clave. Desde la salida de depuración, puede ver que la prueba de expresiones regulares que se envía pasa, pero obviamente falla cuando se prueba en el código. Esto está en línea con lo que veo en mi proyecto, donde si omito la salida de depuración, el valor de retorno básicamente alterna entre verdadero y falso.

Esencialmente la función /regex/.test(value) parece oscilar entre verdadero y falso, lo que es consistente pero no es lo que esperaba ... Entonces, mi pregunta es ¿qué está causando este extraño comportamiento?

He probado mi regex fuera de la solución y, por lo que puedo ver, funciona.

ACTUALIZACIÓN:

La omisión de la 'g' o indicador global de mi expresión regular resolvieron este problema.

Ver la respuesta de abajo y entonces este enlace para obtener una explicación completa del indicador global y sus trampas:

Why RegExp with global flag in Javascript give wrong results?

Respuesta

19

que se reduce al hecho de que el método de javascript expresiones regulares test devuelve un resultado y mueve un puntero hasta después del partido.

Así que la primera llamada devuelve verdadero, luego la segunda devuelve falso. Compruebe este ejemplo: http://jsfiddle.net/B9aVA/

var regex = /^.+$/g 
var input = "Hello"; 
console.log(regex.test(input)); 
console.log(regex.test(input)); 

Escribe

true 
false 

lo que el código que llama a prueba dos veces:

case "regex": 
    $(".debug-info").append('<span>Result: ' + validation[i].rule.test(value) + '</span><br />'); 
    if (!validation[i].rule.test(value)) 
      returnValue.isValid = false; 
    break; 

Mi sugerencia es llamar test una vez y almacenar el resultado en una variable, y use eso en su lugar

case "regex": 
    var result = validation[i].rule.test(value); 
    $(".debug-info").append('<span>Result: ' + result + '</span><br />'); 
    if (!result) 
      returnValue.isValid = false; 
    break; 

Moraleja de la historia: los métodos pueden tener efectos secundarios, eso es lo que los distingue de las propiedades.

+0

Fiddle actualizado: http://jsfiddle.net/Ym2hW/2/ Así que ahora tengo consistencia entre 'test()' y el valor de retorno. Pero si desencadenas el desenfoque varias veces, obtienes las mismas oscilaciones ... ¿Cómo te saldrías con esto? – Jon

+1

Bien, entonces el problema radica en la bandera global, consulte mi actualización más arriba. – Jon

+0

¡Gracias! Cuando dejé caer el indicador global 'g' de mi expresión regular, el problema del resultado' test() 'almacenado desapareció. Con la bandera global alrededor del 20% de la expresión regular adicional.las llamadas de prueba() fallaron cuando eran válidas. –

Cuestiones relacionadas