2009-03-03 11 views
8

Ho scritto un test RegExp Javascript per rilevare il formato di stringa di data, ho aggiunto per errore un flag "g" ridondante e ho trovato qualcosa di interessante.Test interessante di Javascript RegExp

var s = "2009/03/10"; 
var regex=/^\d{4}[/]\d{2}[/]\d{2}$/g; 
alert(regex.test(s)); 
alert(regex.test(s)); 
alert(regex.test(s)); 
alert(regex.test(s)); 

ho avuto un 'vero' seguita da un 'falso', poi un altro 'vero', poi un altro 'false'.

Se utilizzo un loop per eseguirlo, ho trovato qualcosa di più interessante, ho ottenuto quattro "true" in IE e Safari e true, false, true, false in FF, Chrome.

for (var i=0; i<4; i++) 
{ 
    var s = "2009/03/10"; 
    var regex=/^\d{4}[/]\d{2}[/]\d{2}$/g; 
    alert(regex.test(s)); 
} 

Qualcuno ha idea di spiegare perché l'espressione regolare Javascript si comporta in quel modo e che cosa causa i browser restituire risultati diversi? (relativo alla dichiarazione delle variabili e al campo di applicazione?)

risposta

19

Quando si utilizza un flag globale su un JS RegExp, i metodi "test" e "exec" si fermano ciascuno alla prima corrispondenza ma mantengono un puntatore sul punto in cui hanno interrotto la ricerca nel stringa. Quel puntatore può essere controllato sulla proprietà lastIndex. Quando chiami di nuovo "test" o "exec", inizia la ricerca di una corrispondenza a partire dal lastIndex.

Quindi, quando si verifica un RegExp su una stringa che corrisponde all'intera stringa, lastIndex viene impostato alla fine della stringa. La volta successiva che si esegue il test, inizia alla fine della stringa, restituisce false e imposta lastIndex su zero.

L'MDC ha un decent explanation di questo comportamento.

+0

Grazie mille, spiegazione del MDC è molto chiaro. – Darkthread

+0

+1 grazie per l'aiuto, impostando reg.lastIndex = 0 prima che ogni test risolvesse il mio problema. – bendewey

+0

Sembra che tu possa impostare lastIndex = 0 prima di ogni test se questo causa problemi all'interno di un ciclo, ad esempio. – k0nG

0

Per evitare questo comportamento strano non utilizzare il flag globale (g).

Questo codice dovrebbe uscita: 'True', 'True', 'True', 'True'

var s = "2009/03/10"; 
var regex=/^\d{4}[/]\d{2}[/]\d{2}$/i; 
alert(regex.test(s)); 
alert(regex.test(s)); 
alert(regex.test(s)); 
alert(regex.test(s)); 

Il globale (g) piatta impostare la RegExp.lastIndex proprietà. Quindi ogni test() inizierà dove l'ultimo si è fermato.

Per maggiori informazioni visita la documentazione circa RegExp.lastIndex

Problemi correlati