2010-09-28 4 views
9

J'utilise le Javascript suivant pour lire les chaînes d'un fichier texte et de les traiter avec une expression régulièreJavascript Expression régulière échoue tous les temps, il est appelé

while (!textFile.AtEndOfStream) 
{ 
    currLine = textFile.ReadLine(); 
    match = re.exec(currLine); 
    do stuff with match 
} 

Le problème que j'ai est que tous les temps re.exec est appelé il échoue et renvoie null; Ainsi, la première ligne est traitée correctement, mais la deuxième ligne renvoie null, puis la troisième ligne fonctionne et la quatrième ligne renvoie null.

je peux utiliser le code suivant pour obtenir le résultat que je veux

while (!textFile.AtEndOfStream) 
{ 
    currLine = textFile.ReadLine(); 
    match = re.exec(currLine); 
    if (match == null) match = re.exec(currLine); 
} 

mais qui semble un peu bidouille méchant. Quelqu'un peut-il me dire pourquoi cela arrive et ce que je peux faire pour le réparer correctement?

+0

Andy E a la bonne solution, mais si cela vous intéresse, vous pouvez changer cette dernière ligne en 'match = match || re.exec (currLine); ' – Skilldrick

+0

@Skilldrick: supprimé le mien, parce que la réponse de Bobince était plus complète. Maintenant, il a la bonne solution :-) –

Répondre

21

Votre re est défini avec le modificateur « global », par exemple. quelque chose comme /foo/g. Lorsqu'un RegExp est global, il conserve l'état caché dans l'instance RegExp elle-même pour se souvenir du dernier endroit auquel elle correspondait. La prochaine fois que vous effectuerez une recherche, elle sera recherchée dans l'index de la fin du dernier match et trouvera le prochain match à partir de là. Si vous passez une différente chaîne à celle que vous avez passée la dernière fois, cela donnera des résultats hautement imprévisibles! Lorsque vous utilisez des expressions rationnelles lobales g, vous devez les épuiser en les appelant de manière répétée jusqu'à ce que vous obteniez null. Ensuite, la prochaine fois que vous l'utiliserez, vous retrouverez le début de la chaîne. Vous pouvez également définir explicitement re.lastIndex sur 0 avant d'en utiliser un. Si vous voulez seulement tester l'existence d'une correspondance, comme dans cet exemple, le plus simple est de ne pas utiliser g.

Les interfaces JS RegExp sont l'une des parties du langage les plus confuses et mal conçues. (Et c'est JavaScript, donc cela en dit long.)

+1

+1, supprimé le mien en faveur de cela. Je voulais m'étendre sur le mien mais je me suis laissé distraire :-) –

+0

Merci pour l'excellente réponse de Bobince. J'ai enlevé le g et ça fonctionne parfaitement maintenant. – Pandelon

3

Les expressions régulières Javascript conservent un certain état entre les exécutions et vous tombez probablement dans ce piège.

J'utilise toujours la fonction String.match et ne l'ai jamais été mordu:

while (!textFile.AtEndOfStream) 
{ 
    match = textFile.ReadLine().match (re); 
    do stuff with match 
} 
Questions connexes