174 votes

Ce qui ' la différence entre « groupes » et « capture » dans les expressions régulières .NET ?

Je suis un peu floue de ce qu'est la différence entre un "groupe" et une "capture" sont quand il s'agit de .NET de l'expression régulière de la langue. Considérons le code C# suivant:

MatchCollection matches = Regex.Matches("{Q}", @"^\{([A-Z])\}$");

Je m'attends à ce résultat en une seule saisie pour la lettre "Q", mais si j'ai l'impression que les propriétés de l'retourné MatchCollection, je vois:

matches.Count: 1
matches[0].Value: {Q}
        matches[0].Captures.Count: 1
                matches[0].Captures[0].Value: {Q}
        matches[0].Groups.Count: 2
                matches[0].Groups[0].Value: {Q}
                matches[0].Groups[0].Captures.Count: 1
                        matches[0].Groups[0].Captures[0].Value: {Q}
                matches[0].Groups[1].Value: Q
                matches[0].Groups[1].Captures.Count: 1
                        matches[0].Groups[1].Captures[0].Value: Q

Ce qui se passe exactement ici? Je comprends qu'il y a aussi une capture pour le match en entier, mais comment les groupes? Et pourquoi ne pas matches[0].Captures : capture de la lettre "Q"?

132voto

Abel Points 24335

Vous ne serez pas le premier qui est floue à ce sujet. Voici ce que le célèbre Jeffrey Friedl a à dire à ce sujet (pages 437+):

Selon votre point de vue, il ajoute une intéressante nouvelle dimension à la les résultats des matchs, ou ajoute de la confusion et de la météorisation.

Et plus loin:

La principale différence entre un Groupe objet et une Capture de l'objet, c'est que chaque Groupe contient un objet collection d'images représentant tous l' intermédiaire des correspondances par l' le groupe durant le match, ainsi que la texte final compensée par le groupe.

Et quelques pages plus loin, c'est sa conclusion:

Après avoir passé l' .NET la documentation et la réalité la compréhension de ce que ces objets ajouter, J'ai des sentiments mitigés au sujet de eux. Sur d'une part, c'est intéressant l'innovation [ ... ] sur l'autre main, il semble ajouter une efficacité fardeau [..] une fonctionnalité qui ne sera pas utilisé dans la majorité des cas

En d'autres termes: ils sont très similaires, mais de temps en temps et, comme il arrive, vous aurez à trouver un emploi pour eux. Avant d'augmenter à nouveau de barbe grise, vous pouvez même prendre goût à la Capture...


Depuis ni la, ni ce qui est dit dans l'autre post semble vraiment répondre à votre question, considérons l'exemple suivant. Pense de Capture comme une sorte d'histoire tracker. Lorsque la regex fait son match, elle passe à travers la chaîne de gauche à droite (en ignorant retour en arrière pour un moment) et quand il rencontre un correspondant de la capture de parenthèses, il va la stocker dans $x (x étant un chiffre), disons $1.

Normal regex moteurs, lorsque la capture de parenthèses doivent être répétées, va jeter l'actuel $1 et la remplacer par la nouvelle valeur. Pas .NET, ce qui permettra à cette histoire et le place dans Captures[0].

Si nous changeons votre regex présente comme suit:

MatchCollection matches = Regex.Matches("{Q}{R}{S}", @"(\{[A-Z]\})+");

vous noterez que le premier Group aura un Captures (le premier groupe étant toujours l'ensemble du match, c'est à dire, égal à $0) et le deuxième groupe tiendra {S}, c'est à dire que le dernier de groupe correspondant. Cependant, et là est le hic, si vous voulez trouver les deux autres captures, ils sont en Captures, qui contient tous les intermédiaires de capture pour {Q} {R} et {S}.

Si vous jamais demandé comment vous pourriez obtenir à partir de la capture, qui n'affiche que le dernier match de l'individu capture qui sont clairement là dans la chaîne, vous devez utiliser Captures.

Un dernier mot sur votre dernière question: le total des match a toujours un total de Capture, ne pas le mélanger avec les différents Groupes. Capture ne sont intéressants à l'intérieur des groupes.

23voto

Gerard ONeill Points 319

Un Groupe, c'est ce que nous avons associés à des groupes dans les expressions régulières

"(a[zx](b?))"

Applied to "axb" returns an array of 3 groups:

group 0: axb, the entire match.
group 1: axb, the first group matched.
group 2: b, the second group matched.

sauf que ce ne sont que des "capturée" par les groupes. Non de capturer les groupes (à l'aide de l' '(?: 'la syntaxe ne sont pas représentés ici.

"(a[zx](?:b?))"

Applied to "axb" returns an array of 2 groups:

group 0: axb, the entire match.
group 1: axb, the first group matched.

Une Capture est aussi ce que nous avons associés à "capturée groupes". Mais lorsque le groupe est appliqué avec un quantificateur plusieurs fois, seul le dernier match est maintenu tant que le groupe de correspondance. La capture de la matrice de tous les magasins de ces matches.

"(a[zx]\s+)+"

Applied to "ax az ax" returns an array of 2 captures of the second group.

group 1, capture 0 "ax "
group 1, capture 1 "az "

Quant à votre dernière question, j'aurais pensé avant de regarder ce que Capture serait un tableau de la capture commandé par le groupe auquel ils appartiennent. Mais plutôt que c'est juste un alias pour les groupes[0].Les Captures. Assez inutile..

15voto

pmarflee Points 2788

À partir de MSDN documentation:

L'utilité réelle de la Capture de la propriété se produit lorsqu'un quantificateur est appliqué à une capture d'un groupe de sorte que le groupe saisit de multiples sous-chaînes dans une seule expression régulière. Dans ce cas, le Groupe de l'objet contient des informations sur la dernière capturée, alors que la Capture de la propriété contient des informations sur toutes les sous-chaînes capturées par le groupe. Dans l'exemple suivant, l'expression régulière \b(\w+\s*)+. correspond à un ensemble de la phrase qui se termine par une période. Le groupe (\w+\s*)+ capture les mots de la collection. Parce que le Groupe collection contient uniquement des informations sur la dernière capturée, elle capte le dernier mot dans la phrase, "phrase". Cependant, chaque mot capturé par le groupe sont disponibles à partir de la collection retournée par la Capture de la propriété.

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