2012-02-14 18 views
5

Mi sembra di avere un risultato costantemente strano quando collaudo la mia regex in javascript.Il regex Javascript dovrebbe passare .test() ma sembra fallire - perché?

Ecco il mio violino: http://jsfiddle.net/s5fYf/15/

Questo è tratto da un progetto web che sto costruendo. Passo una matrice di oggetti di convalida nella mia funzione di convalida che itera attraverso di essi, convalidando ogni regola contro il valore. Se uno è falso, dovrebbe interrompere il loop e restituire un oggetto return che preleva un messaggio e cssClass dalla regola fallita.

Il problema è che il metodo di convalida sembra restituire false anche se il test regex passa, il che dovrebbe essere impossibile! Quindi mi sento come se mi mancasse qualcosa chiave. Dall'output di debug si può vedere che il test di regex che viene emesso passa, ma ovviamente fallisce quando viene testato nel codice. Questo è in linea con quello che vedo nel mio progetto, in cui, se ometto l'output di debug, il valore di ritorno passa fondamentalmente da true a false.

Essenzialmente la funzione /regex/.test(value) sembra oscillare tra vero e falso che è coerente ma non quello che mi aspettavo ... Quindi, la mia domanda è che cosa sta causando questo comportamento bizzarro !?

Ho testato il mio regex al di fuori della soluzione e per quanto posso vedere funziona.

UPDATE:

Tralasciando la 'g' o flag globale dal mio regex risolto questo problema.

Vedere la risposta qui sotto e poi questo link per una spiegazione completa della bandiera globale e le sue insidie:

Why RegExp with global flag in Javascript give wrong results?

risposta

19

si riduce al fatto che il metodo di Javascript espressioni regolari test restituisce un risultato e sposta un puntatore su dopo la partita.

Quindi la prima chiamata restituisce true, quindi la seconda restituisce false. Controllare questo esempio: http://jsfiddle.net/B9aVA/

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

Scrive

true 
false 

Quindi il codice che chiama test due volte:

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

Il mio suggerimento è quello di chiamare test una volta e memorizzare il risultato in una variabile, e usa quello invece

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

Morale della trama: i metodi possono avere effetti collaterali, questo è ciò che li distingue dalle proprietà.

+0

Fiddle aggiornato: http://jsfiddle.net/Ym2hW/2/ Così ora ottengo la coerenza tra 'test()' e il valore restituito. Ma se si attiva l'offuscamento più volte si ottengono le stesse oscillazioni .. Come si aggirerebbe questo? – Jon

+1

Ok, quindi il problema si trova con la bandiera globale, vedi il mio aggiornamento sopra. – Jon

+0

Grazie! Quando ho eliminato la flag globale 'g' dalla mia regex il problema del risultato' test() 'è andato via. Con la bandiera globale circa il 20% della regex aggiuntiva.le chiamate test() non sono riuscite quando erano valide. –

Problemi correlati