Captura e agrupamento
Grupo de captura (pattern)
cria um grupo que possui propriedade de captura .
Um relacionado que você pode ver (e usar) com frequência é o (?:pattern)
, que cria um grupo sem capturar propriedade, portanto, denominado grupo de não captura .
Um grupo é geralmente usado quando você precisa repetir uma sequência de padrões, por exemplo (\.\w+)+
, ou para especificar onde a alternância deve ter efeito, por exemplo ^(0*1|1*0)$
( ^
, então 0*1
ou 1*0
, então $
) versus ^0*1|1*0$
( ^0*1
ou 1*0$
).
Um grupo de captura, além do agrupamento, também gravará o texto correspondente ao padrão dentro do grupo de captura (pattern)
. Usando o seu exemplo, (.*):
, .*
jogosABC
e :
jogos :
, e uma vez que .*
está dentro de grupo de captura (.*)
, o texto ABC
é gravado para o grupo de captura 1.
Número do grupo
Todo o padrão é definido como o número do grupo 0.
Qualquer grupo de captura no padrão começa a indexação de 1. Os índices são definidos pela ordem dos parênteses de abertura dos grupos de captura . Por exemplo, aqui estão todos 5 grupos de captura no padrão abaixo:
(group)(?:non-capturing-group)(g(?:ro|u)p( (nested)inside)(another)group)(?=assertion)
| | | | | | || | |
1-----1 | | 4------4 |5-------5 |
| 3---------------3 |
2-----------------------------------------2
Os números do grupo são usados na referência anterior \n
no padrão e $n
na string de substituição.
Em outros tipos de regex (PCRE, Perl), eles também podem ser usados em chamadas de sub-rotina .
Você pode acessar o texto correspondido por determinado grupo com Matcher.group(int group)
. Os números dos grupos podem ser identificados com a regra indicada acima.
Em alguns tipos de regex (PCRE, Perl), há um recurso de redefinição de ramificação que permite usar o mesmo número para capturar grupos em diferentes ramificações de alternância .
Nome do grupo
No Java 7, você pode definir um grupo de captura nomeado (?<name>pattern)
e pode acessar o conteúdo correspondente Matcher.group(String name)
. A regex é mais longa, mas o código é mais significativo, pois indica o que você está tentando corresponder ou extrair com a regex.
Os nomes dos grupos são usados na referência anterior \k<name>
no padrão e ${name}
na string de substituição.
Os grupos de captura nomeados ainda são numerados com o mesmo esquema de numeração, portanto, também podem ser acessados via Matcher.group(int group)
.
Internamente, a implementação do Java mapeia apenas do nome ao número do grupo. Portanto, você não pode usar o mesmo nome para 2 grupos de captura diferentes.
Para o resto de nós
Aqui está um exemplo simples e claro de como isso funciona
Regex:
([a-zA-Z0-9]+)([\s]+)([a-zA-Z ]+)([\s]+)([0-9]+)
Corda:
"!* UserName10 John Smith 01123 *!"
Como você pode ver, criei CINCO grupos, cada um entre parênteses.
Incluí! * E *! em ambos os lados para torná-lo mais claro. Observe que nenhum desses caracteres está no RegEx e, portanto, não serão produzidos nos resultados. Grupo (0) apenas fornece a string inteira correspondida (todos os meus critérios de pesquisa em uma única linha). O grupo 1 para logo antes do primeiro espaço porque o caractere de espaço não foi incluído nos critérios de pesquisa. Os grupos 2 e 4 são simplesmente o espaço em branco, que neste caso é literalmente um caractere de espaço, mas também pode ser uma guia ou uma alimentação de linha etc. O grupo 3 inclui o espaço porque eu o coloquei nos critérios de pesquisa ... etc.
Espero que isso faça sentido.
fonte
Parêntese
()
são usados para permitir o agrupamento de frases regex.O
group(1)
contém a string que está entre parênteses,(.*)
então.*
neste casoE
group(0)
contém toda a string correspondente.Se você tivesse mais grupos (ler
(...)
), seria colocado em grupos com os próximos índices (2, 3 e assim por diante).fonte