Tentando entender “Capturando grupos” no regex com Java

Eu estou estudando para o java OCP e no momento estou preso em entender a seção “Capturando grupos” . É uma forma abstrata demais como uma descrição. Você poderia por favor (se você tiver tempo) dar-me alguns exemplos reais usando “Capturando grupos”?

Alguém é capaz de me fornecer um exemplo concreto da seguinte declaração?

Capturar grupos é uma maneira de tratar vários caracteres como uma única unidade. Eles são criados colocando os caracteres a serem agrupados dentro de um conjunto de parênteses. Por exemplo, a expressão regular (dog) cria um único grupo contendo as letras “d” “o” e “g”. A parte da cadeia de input que corresponde ao grupo de captura será guardada na memory para uma chamada posterior através de referências anteriores (tal como discutido abaixo na secção Backreferences).

Tenho certeza de que vou recebê-lo assim que eu vir um exemplo concreto.

Desde já, obrigado.

Entre outras coisas, o regex permite obter partes da input que foram correspondidas por várias partes da expressão regular. Às vezes você precisa de todo o jogo, mas muitas vezes você precisa apenas de uma parte dele. Por exemplo, esta expressão regular corresponde a cadeias de caracteres "Page X of Y" :

 Page \d+ of \d+ 

Se você passar uma string

 Page 14 of 203 

você irá combinar a string inteira. Agora vamos dizer que você quer apenas 14 e 203 . Não há problema – a biblioteca regex permite colocar os dois \d+ entre parênteses e, em seguida, recuperar apenas as sequências "14" e "203" da correspondência.

 Page (\d+) of (\d+) 

A expressão acima cria dois grupos de captura . O object Matcher obtido pela correspondência do padrão permite recuperar o conteúdo desses grupos individualmente:

 Pattern p = Pattern.compile("Page (\\d+) of (\\d+)"); String text = "Page 14 of 203"; Matcher m = p.matcher(text); if (m.find()) { System.out.println(m.group(1)); System.out.println(m.group(2)); } 

Isso imprime 14 e 203 .

Demo no ideone .

Os grupos de captura permitem consultar o Matcher para descobrir qual a parte da string que correspondeu a uma parte específica da expressão regular, consulte este exemplo:

 String dateStr = "1981-06-25"; Pattern datePatt = Pattern.compile("([0-9]{4})/([0-9]{2})/([0-9]{2})"); ... Matcher m = datePatt.matcher(dateStr); if (m.matches()) { int year = Integer.parseInt(m.group(1)); int month = Integer.parseInt(m.group(2)); int day = Integer.parseInt(m.group(3)); } 

As variables ​​ano, mês e dia contêm o valor dos grupos 1, 2 e 3, respectivamente.

É por isso que você quer acompanhar partes do jogo. Por exemplo, se você tiver o regex

/^(http|ftp).*/

e você recebe uma correspondência, você pode consultar a correspondência para o grupo e dizer se foi http ou ftp.

Por exemplo, tome o regex

 cat (dog )?bus 

Isto irá coincidir com as duas cadeias de cat dog bus e cat bus . Isso porque a parte inteira do dog é opcional por causa do ? . Se você não o embrulhou no paren, somente o último espaço seria opcional.

 James while John (had )+a better effect on the teacher 

corresponderá à string

 James while John had had had had had had had had had had had a better effect on the teacher 

como ele corresponderá a uma ou mais de toda a cadeia de caracteres.

Você também pode usar referências de alternância e retrocesso com grupos de captura (algo que você ainda não chegou).

 (cat|dog) is a \1 

O \1 é uma referência ao que foi capturado no primeiro grupo de captura. Isso vai combinar dog is a dog e cat is a cat , mas não o dog is a cat ou vice-versa.

Aqui você vê alguns exemplos de código que você pode entender facilmente.

Basicamente, o que você tem dentro de () você se lembra após o jogo. E você pode ver a string correspondente a esse grupo. Lembre-se de que, se você fizer uma segunda correspondência, esses valores serão substituídos pela segunda correspondência, portanto, se você precisar deles, precisará salvá-los imediatamente após a correspondência em algumas variações definidas por você.