Expressions et sous-matches réguliers JavaScript

Pourquoi les sous-correspondances Javascript cessent-ils de fonctionner lorsque le modificateur g est réglé?

 var text = 'test test test test'; var result = text.match(/t(e)(s)t/); // Result: ["test", "e", "s"] 

Ce qui précède fonctionne bien, le result[1] est "e" et le result[2] est "s" .

 var result = text.match(/t(e)(s)t/g); // Result: ["test", "test", "test", "test"] 

Ce qui précède ignore mes groupes de capture. La solution unique est-elle la suivante?

 var result = text.match(/test/g); for (var i in result) { console.log(result[i].match(/t(e)(s)t/)); } /* Result: ["test", "e", "s"] ["test", "e", "s"] ["test", "e", "s"] ["test", "e", "s"] */ 

L'utilisation de la fonction match() String ne renverra pas les groupes capturés si le modificateur global est défini, comme vous l'avez découvert.

Dans ce cas, vous souhaitez utiliser un objet RegExp et appeler sa fonction exec() . String match() est presque identique à la fonction exec() de RegExp … sauf dans des cas comme ceux-ci. Si le modificateur global est défini, la fonction de match() normale match() ne renverra pas les groupes capturés, alors que la fonction exec() RegExp sera. (Noté ici , entre autres endroits).

Une autre capture à retenir est que exec() ne renvoie pas les correspondances dans un grand tableau: il conserve les correspondances jusqu'à ce qu'il soit épuisé, auquel cas il renvoie null .

Ainsi, par exemple, vous pouvez faire quelque chose comme ceci:

 var pattern = /t(e)(s)t/g; // Alternatively, "new RegExp('t(e)(s)t', 'g');" var match; while (match = pattern.exec(text)) { // Do something with the match (["test", "e", "s"]) here... } 

Une autre chose à noter est que RegExp.prototype.exec() et RegExp.prototype.test() exécutent l'expression régulière sur la chaîne fournie et renvoient le premier résultat. Chaque appel séquentiel passera à travers la mise à jour du jeu de résultats RegExp.prototype.lastIndex fonction de la position actuelle dans la chaîne.

Voici un exemple: // rappelez-vous qu'il y a 4 correspondances dans l'exemple et le modèle. LastIndex commence à 0

 pattern.test(text); // pattern.lastIndex = 4 pattern.test(text); // pattern.lastIndex = 9 pattern.exec(text); // pattern.lastIndex = 14 pattern.exec(text); // pattern.lastIndex = 19 // if we were to call pattern.exec(text) again it would return null and reset the pattern.lastIndex to 0 while (var match = pattern.exec(text)) { // never gets run because we already traversed the string console.log(match); } pattern.test(text); // pattern.lastIndex = 4 pattern.test(text); // pattern.lastIndex = 9 // however we can reset the lastIndex and it will give us the ability to traverse the string from the start again or any specific position in the string pattern.lastIndex = 0; while (var match = pattern.exec(text)) { // outputs all matches console.log(match); } 

Vous pouvez trouver des informations sur la façon d'utiliser RegExp objets RegExp sur le MDN (en particulier, voici la documentation pour la fonction exec() ).