Você não será o primeiro a ficar confuso com isso. Aqui está o que o famoso Jeffrey Friedl tem a dizer sobre isso (páginas 437 ou mais):
Dependendo da sua visão, ele adiciona uma nova dimensão interessante aos resultados da partida ou confusão e inchaço.
E mais adiante:
A principal diferença entre um objeto de grupo e um objeto de captura é que cada objeto de grupo contém uma coleção de capturas representando todas as correspondências intermediárias pelo grupo durante a correspondência, bem como o texto final correspondente ao grupo.
E algumas páginas depois, esta é sua conclusão:
Depois de passar pela documentação do .NET e realmente entender o que esses objetos adicionam, tenho sentimentos contraditórios sobre eles. Por um lado, é uma inovação interessante [...] por outro lado, parece acrescentar um ônus de eficiência [...] a uma funcionalidade que não será usada na maioria dos casos
Em outras palavras: eles são muito semelhantes, mas ocasionalmente e, por acaso, você encontrará um uso para eles. Antes de cultivar outra barba grisalha, você pode até gostar das Capturas ...
Como nem o exposto acima, nem o que foi dito na outra postagem realmente parece responder à sua pergunta, considere o seguinte. Pense no Capture como um tipo de rastreador de história. Quando o regex faz a correspondência, ele passa pela string da esquerda para a direita (ignorando o retorno por um momento) e quando encontra parênteses de captura correspondentes, o armazena em $x
(x sendo qualquer dígito), digamos $1
.
Os mecanismos regex normais, quando os parênteses de captura devem ser repetidos, jogam fora a corrente $1
e a substituem pelo novo valor. Não é o .NET, que manterá esse histórico e o incluirá Captures[0]
.
Se alterarmos sua regex para a seguinte aparência:
MatchCollection matches = Regex.Matches("{Q}{R}{S}", @"(\{[A-Z]\})+");
você notará que o primeiro Group
terá um Captures
(o primeiro grupo sempre sendo o jogo inteiro, ou seja, igual a $0
) e o segundo grupo será válido {S}
, ou seja, apenas o último grupo correspondente. No entanto, e aqui está o problema, se você quiser encontrar os outros dois, eles estão Captures
, que contém todas as capturas intermediárias para {Q}
{R}
e {S}
.
Se você já se perguntou como poderia obter a captura múltipla, que mostra apenas a última correspondência com as capturas individuais que estão claramente lá na sequência, você deve usar Captures
.
Uma palavra final na sua pergunta final: a correspondência total sempre tem uma captura total, não a misture com os grupos individuais. As capturas são interessantes apenas dentro de grupos .
a functionality that won't be used in the majority of cases
Eu acho que ele perdeu o barco. No curto prazo,(?:.*?(collection info)){4,20}
aumenta a eficiência em mais do que algumas centenas por cento.(?:..)+
. Corresponda preguiçosamente qualquer coisa.*?
até uma subexpressão de captura (grupo). Continue. Em uma única partida, uma coleção de grupos precipita uma matriz do que é necessário. Não há necessidade de encontrar o próximo, não há reentrada tornando-o 10 a 20 ou mais vezes mais rápido.a functionality that won't be used in the majority of cases
. De fato, é a funcionalidade mais procurada em regiões regex. Preguiçoso / ganancioso? O que isso tem a ver com meus comentários? Permite ter uma quantidade variável de buffers de captura. Ele pode varrer toda a cadeia em uma única correspondência. Se.*?(dog)
encontrar o primeirodog
,(?:.*?(dog))+
encontrará tudodog
em toda a sequência em uma única correspondência. O aumento de desempenho é perceptível.Um grupo é o que associamos a grupos em expressões regulares
exceto que esses são apenas grupos 'capturados'. Grupos que não capturam (usando a sintaxe '(?:') Não são representados aqui.
Uma captura também é o que associamos aos 'grupos capturados'. Porém, quando o grupo é aplicado com um quantificador várias vezes, apenas a última correspondência é mantida como a correspondência do grupo. A matriz de capturas armazena todas essas correspondências.
Quanto à sua última pergunta - eu teria pensado antes de examinar isso que o Capture seria um conjunto de capturas ordenadas pelo grupo ao qual pertencem. Pelo contrário, é apenas um apelido para os grupos [0]. Muito inútil ..
fonte
Isso pode ser explicado com um exemplo simples (e imagens).
Correspondendo
3:10pm
à expressão regular((\d)+):((\d)+)(am|pm)
e usando o Mono Interactivecsharp
:Então, onde está o 1?
Como existem vários dígitos correspondentes no quarto grupo, apenas "chegamos" à última correspondência se fizermos referência ao grupo (com um implícito
ToString()
). Para expor as correspondências intermediárias, precisamos nos aprofundar e fazer referência àCaptures
propriedade no grupo em questão:Cortesia deste artigo .
fonte
Na documentação do MSDN :
fonte
Imagine que você tenha a seguinte entrada de texto
dogcatcatcat
e um padrão comodog(cat(catcat))
Nesse caso, você tem 3 grupos, o primeiro ( grupo principal ) corresponde à partida.
Corresponder ==
dogcatcatcat
e Grupo0 ==dogcatcatcat
Grupo1 ==
catcatcat
Grupo2 ==
catcat
Então, o que é isso tudo?
Vamos considerar um pequeno exemplo escrito em C # (.NET) usando a
Regex
classeSaída :
Vamos analisar apenas a primeira correspondência (
match0
).Como você pode ver, existem três grupos menores :
group3
,group4
egroup5
Esses grupos (3-5) foram criados devido ao ' sub-padrão '
(...)(...)(...)
do padrão principal(dog(cat(...)(...)(...)))
O valor de
group3
corresponde à sua captura (capture0
). (Como no caso degroup4
egroup5
). Isso ocorre porque não há repetição de grupo como(...){3}
.Ok, vamos considerar outro exemplo em que há uma repetição em grupo .
Se modificar o padrão de expressão regular a ser correspondido (para código mostrado acima) de
(dog(cat(...)(...)(...)))
que(dog(cat(...){3}))
, você notará que há a seguinte repetição grupo :(...){3}
.Agora a saída mudou:
Novamente, vamos analisar apenas a primeira correspondência (
match0
).Não há mais grupos menores
group4
e,group5
devido à(...){3}
repetição ( {n} em que n> = 2 ), eles foram mesclados em um único grupogroup3
.Nesse caso, o
group3
valor corresponde a elecapture2
( a última captura , em outras palavras).Assim, se você precisa de todos os 3 captações internas (
capture0
,capture1
,capture2
) você terá que percorrer do grupoCaptures
coleção.A conclusão é: preste atenção na maneira como você cria os grupos de seus padrões. Você deve pensar antecipadamente o comportamento faz com que a especificação do grupo, como
(...)(...)
,(...){2}
ou(.{3}){2}
etc.Espero que ajude a esclarecer as diferenças entre Capturas , Grupos e Jogos também.
fonte