72 votes

Javascript Regex et Submatches

Pourquoi javascript sous-correspond à arrêter de travailler lorsque le modificateur g est définie?

var text = 'test test test test';

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

le ci-dessus fonctionne très bien... [1] e et [2] est s... parfait

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

le ci-dessus ignore mon sous-correspondances

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

est la au-dessus de la seule solution valable?


solution:

grâce à htw la bonne façon de le faire serait le suivant:

var text = 'test test test test',
    pattern = new RegExp(/t(e)(s)t/g),
    match;

while (match = pattern.exec(text)) {
    console.log(match);
}

RegExp.le prototype.lastIndex manipulation

RegExp.le prototype.exec et RegExp.le prototype.test d'exécuter l'expression régulière sur la condition de chaîne et retour le premier résultat. Chaque séquentielle appel d'étape à travers le jeu de résultats de la mise à jour RegExp.le prototype.lastIndex fonction de la position actuelle dans la chaîne, alors soyez prudent.

heres un exemple

// remember there are 4 matches in the example and pattern.lastIndex starts at 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 false and reset the pattern.lastIndex to 0
while (match = pattern.exec(text)) {
    // never gets ran 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 or any specific position in the string
pattern.lastIndex = 0;

while (match = pattern.exec(text)) {
    // outputs all of the matches
    console.log(match);
}

100voto

htw Points 10312

À l'aide de Strings' match() fonction ne retourne pas capturé groupes si l'option est activée, comme vous l'avez trouvé.

Dans ce cas, vous souhaitez utiliser un RegExp objet et l'appel de son exec() fonction. Strings' match() est presque identique à l' RegExps' exec() fonction...sauf dans des cas comme ceux-ci. Si l'option est activée, la normale match() fonction ne retourne pas capturé groupes, tandis que d' RegExps' exec() fonction. (Noté ici, parmi d'autres endroits.)

Un autre attraper à retenir est que, exec() ne retourne pas les matches en un grand tableau-il conserve son retour matches jusqu'à ce qu'elle s'épuise, auquel cas il renvoie null.

Ainsi, par exemple, vous pourriez 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...
}

Vous pouvez trouver des informations sur la façon d'utiliser RegExp objets sur W3Schools (plus précisément, voici la documentation de l' exec() de la fonction).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X