1309 votes

Comment avez-vous accès à la correspondance des groupes de dans une expression régulière en JavaScript?

Je veux correspondre à une partie d'une chaîne à l'aide d'une expression régulière , puis accéder aux sous-chaîne entre parenthèses:

var myString = "something format_abc"; // I want "abc"

var arr = /(?:^|\s)format_(.*?)(?:\s|$)/.exec(myString);

console.log(arr);     // Prints: [" format_abc", "abc"] .. so far so good.
console.log(arr[1]);  // Prints: undefined  (???)
console.log(arr[0]);  // Prints: format_undefined (!!!)

Ce que je fais mal?


J'ai découvert qu'il n'y a rien de mal avec l'expression régulière code ci-dessus: la chaîne qui j'ai été le tester contre c'était ça:

"date format_%A"

Signalé que "%" n'est pas défini semble très étrange comportement, mais il n'est pas directement liée à cette question, j'ai donc ouvert un nouveau, Pourquoi est-ce une sous-chaîne correspondante de retour "undefined" en JavaScript?.


Le problème était qu' console.log prend ses paramètres comme un printf déclaration, et depuis la chaîne, j'ai été la journalisation ("%A") avait une valeur particulière, il essayait de trouver la valeur du paramètre suivant.

1620voto

CMS Points 315406

Vous pouvez accéder à la capture des groupes comme ceci:

var myString = "something format_abc";
var myRegexp = /(?:^|\s)format_(.*?)(?:\s|$)/g;
var match = myRegexp.exec(myString);
alert(match[1]);  // abc

Et si il y a des correspondances multiples, vous pouvez effectuer une itération sur eux:

match = myRegexp.exec(myString);
while (match != null) {
    // matched text: match[0]
    // match start: match.index
    // capturing group n: match[n]
    match = myRegexp.exec(myString);
}

183voto

Mathias Bynens Points 41065

Voici une méthode que vous pouvez utiliser pour obtenir le nth capture d'un groupe pour chaque match:

function getMatches(string, regex, index) {
    index || (index = 1); // default to the first capturing group
    var matches = [];
    var match;
    while (match = regex.exec(string)) {
        matches.push(match[index]);
    }
    return matches;
}

Exemple:

var myString = 'something format_abc something format_def something format_ghi';
var myRegEx = /(?:^|\s)format_(.*?)(?:\s|$)/g;

// Get an array containing the first capturing group for every match
var matches = getMatches(myString, myRegEx, 1);
// matches → ['abc', 'def', 'ghi']

56voto

PhiLho Points 23458
var myString = "something format_abc";
var arr = myString.match(/\bformat_(.*?)\b/);
console.log(arr[0] + " " + arr[1]);

Le \b n'est pas exactement la même chose (œuvres "--format_foo/", ne fonctionne pas sur "format_a_b")... Mais je voulais montrer une alternative à votre expression, ce qui est bien. Bien sûr, le match d'appel est la chose la plus importante.

30voto

Alexz Points 1

En ce qui concerne le multi-match entre parenthèses les exemples ci-dessus, je cherchais une réponse ici, après ne pas avoir ce que je voulais à partir de:

var matches = mystring.match(/(?:neededToMatchButNotWantedInResult)(matchWanted)/igm);

D'après le peu alambiqué appels de fonction avec tout et .push() ci-dessus, il m'est apparu que le problème peut être résolu très élégamment avec mystring.replace() à la place (le remplaçant n'est PAS au point, et n'est pas encore fait, le PROPRE, intégré dans la fonction récursive de l'option d'achat pour le deuxième paramètre est!):

var yourstring = 'something format_abc something format_def something format_ghi';

var matches = [];
yourstring.replace(/format_([^\s]+)/igm, function(m, p1){ matches.push(p1); } );

Après cela, je ne pense pas que je suis jamais allez utiliser .match() pour presque rien de nouveau.

17voto

Jonathan Lonowski Points 45253

Votre syntaxe n'est probablement pas la meilleure façon de le conserver. FF/Gecko définit RegExp comme une extension de la Fonction.
(FF2 est allé jusqu' typeof(/pattern/) == 'function')

Il semble que ce soit spécifique à FF -- IE, Opera, Chrome et tous lancer des exceptions.

Au lieu de cela, utilisez l'une des méthodes mentionnées précédemment par d'autres: - RegExp#exec ou String#match.
Ils offrent les mêmes résultats:

var regex = /(?:^|\s)format_(.*?)(?:\s|$)/;
var input = "something format_abc";

regex(input);        //=> [" format_abc", "abc"]
regex.exec(input);   //=> [" format_abc", "abc"]
input.match(regex);  //=> [" format_abc", "abc"]

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