Vous ne serez pas le premier à être flou à ce sujet. Voici ce que le célèbre Jeffrey Friedl en dit (pages 437+):
Selon votre point de vue, cela ajoute une nouvelle dimension intéressante aux résultats du match, ou ajoute de la confusion et du gonflement.
Et plus loin:
La principale différence entre un objet Group et un objet Capture est que chaque objet Group contient une collection de Captures représentant toutes les correspondances intermédiaires par le groupe pendant la correspondance, ainsi que le texte final mis en correspondance par le groupe.
Et quelques pages plus tard, voici sa conclusion:
Après avoir dépassé la documentation .NET et compris ce que ces objets ajoutent, j'ai des sentiments mitigés à leur sujet. D'une part, c'est une innovation intéressante [..] d'autre part, elle semble ajouter une charge d'efficacité [..] d'une fonctionnalité qui ne sera pas utilisée dans la majorité des cas
En d'autres termes: ils sont très similaires, mais parfois et au fur et à mesure, vous leur trouverez une utilité. Avant de faire pousser une autre barbe grise, vous pouvez même vous adonner aux Captures ...
Étant donné que ni ce qui précède, ni ce qui est dit dans l'autre article ne semble vraiment répondre à votre question, considérez ce qui suit. Considérez Captures comme une sorte de suivi de l'historique. Lorsque l'expression régulière fait sa correspondance, elle parcourt la chaîne de gauche à droite (en ignorant le retour arrière pendant un moment) et lorsqu'elle rencontre une parenthèse de capture correspondante, elle la stockera dans $x
(x étant n'importe quel chiffre), disons $1
.
Les moteurs de regex normaux, lorsque les parenthèses de capture doivent être répétées, jetteront le courant $1
et le remplaceront par la nouvelle valeur. Pas .NET, qui conservera cette histoire et la placera dans Captures[0]
.
Si nous changeons votre expression régulière pour qu'elle ressemble à ceci:
MatchCollection matches = Regex.Matches("{Q}{R}{S}", @"(\{[A-Z]\})+");
vous remarquerez que le premier en Group
aura un Captures
(le premier groupe étant toujours le match complet, c'est-à-dire égal à $0
) et le second groupe tiendra {S}
, c'est-à-dire seulement le dernier groupe correspondant. Cependant, et voici la capture, si vous voulez trouver les deux autres captures, elles sont dans Captures
, qui contient toutes les captures intermédiaires pour {Q}
{R}
et {S}
.
Si vous vous êtes déjà demandé comment vous pourriez obtenir de la capture multiple, qui ne montre que la dernière correspondance pour les captures individuelles qui sont clairement là dans la chaîne, vous devez utiliser Captures
.
Un dernier mot sur votre dernière question: le match total a toujours une capture totale, ne mélangez pas cela avec les groupes individuels. Les captures ne sont intéressantes qu'à l'intérieur des groupes .
a functionality that won't be used in the majority of cases
Je pense qu'il a raté le bateau. À court terme,(?:.*?(collection info)){4,20}
augmente l'efficacité de plus de quelques centaines de pour cent.(?:..)+
. Faites correspondre paresseusement n'importe quoi.*?
jusqu'à une sous-expression de capture (groupe). Continuez. Dans une seule correspondance, une collection de groupe précipite un tableau de ce qui est nécessaire. Il n'y a pas besoin de trouver ensuite, il n'y a pas de rentrée, ce qui le rend 10 à 20 fois ou plus plus rapide.a functionality that won't be used in the majority of cases
. En fait, c'est la fonctionnalité la plus recherchée dans le monde des regex. Paresseux / gourmand? Qu'est-ce que cela a à voir avec mes commentaires? Il permet d'avoir une quantité variable de tampons de capture. Il peut balayer toute la chaîne en une seule correspondance. Si.*?(dog)
trouve le premier,dog
alors(?:.*?(dog))+
trouvera toutdog
dans la chaîne entière en une seule correspondance. L'augmentation des performances est perceptible.Un groupe est ce que nous avons associé aux groupes dans les expressions régulières
sauf que ce ne sont que des groupes «capturés». Les groupes non capturants (utilisant la syntaxe '(?:' Ne sont pas représentés ici.
Une capture est également ce que nous avons associé aux «groupes capturés». Mais lorsque le groupe est appliqué avec un quantificateur plusieurs fois, seule la dernière correspondance est conservée comme correspondance du groupe. Le tableau de captures stocke toutes ces correspondances.
En ce qui concerne votre dernière question - j'aurais pensé avant d'examiner cela que les captures seraient un tableau des captures ordonnées par le groupe auquel elles appartiennent. Il s'agit plutôt d'un alias des groupes [0] .Captures. Assez inutile.
la source
Cela peut être expliqué par un exemple simple (et des images).
Correspondance
3:10pm
avec l'expression régulière((\d)+):((\d)+)(am|pm)
et utilisation de Mono interactivecsharp
:Alors, où est le 1?
Puisqu'il y a plusieurs chiffres qui correspondent sur le quatrième groupe, nous n'obtenons la dernière correspondance que si nous référençons le groupe (avec un implicite
ToString()
, c'est-à-dire). Afin d'exposer les correspondances intermédiaires, nous devons aller plus loin et référencer laCaptures
propriété sur le groupe en question:Avec l'aimable autorisation de cet article .
la source
À partir de la documentation MSDN :
la source
Imaginez que vous ayez la saisie de texte suivante
dogcatcatcat
et un modèle commedog(cat(catcat))
Dans ce cas, vous avez 3 groupes, le premier ( grand groupe ) correspond au match.
Match ==
dogcatcatcat
et Group0 ==dogcatcatcat
Groupe1 ==
catcatcat
Groupe2 ==
catcat
Alors de quoi s'agit-il?
Prenons un petit exemple écrit en C # (.NET) en utilisant la
Regex
classe.Sortie :
Analysons juste la première correspondance (
match0
).Comme vous pouvez le voir , il y a trois groupes mineurs :
group3
,group4
etgroup5
Ces groupes (3-5) ont été créés en raison du `` sous- modèle ''
(...)(...)(...)
du modèle principal(dog(cat(...)(...)(...)))
La valeur de
group3
correspond à sa capture (capture0
). (Comme dans le cas degroup4
etgroup5
). C'est parce qu'il n'y a pas de répétition de groupe comme(...){3}
.Ok, considérons un autre exemple où il y a une répétition de groupe .
Si nous modifions le modèle d'expression régulière pour être adapté (pour le code ci - dessus) de
(dog(cat(...)(...)(...)))
à(dog(cat(...){3}))
, vous remarquerez qu'il ya les éléments suivants répétition du groupe :(...){3}
.Maintenant, la sortie a changé:
Encore une fois, analysons uniquement la première correspondance (
match0
).Il n'y a plus de groupes mineurs
group4
et àgroup5
cause de la(...){3}
répétition ( {n} où n> = 2 ) ils ont été fusionnés en un seul groupegroup3
.Dans ce cas, la
group3
valeur correspond à ellecapture2
( la dernière capture , en d'autres termes).Ainsi , si vous avez besoin tous les 3 captures intérieures (
capture0
,capture1
,capture2
) vous devrez faire défiler du groupeCaptures
de la collection.La conclusion est la suivante: faites attention à la façon dont vous concevez les groupes de votre modèle. Vous devriez penser dès le départ ce qui cause le comportement des spécifications du groupe, comme
(...)(...)
,(...){2}
ou(.{3}){2}
etc.Espérons que cela aidera également à faire la lumière sur les différences entre les captures , les groupes et les matchs .
la source