Grupos de captura em expressões regulares no PHP

O conteúdo dos grupos de captura não está disponível apenas na string de substituição, mas também na própria expressão regular: nós podemos colocar algo em um grupo e depois, diretamente na expressão regular, indicar que o conteúdo desse grupo deve aparecer aqui.

O conteúdo dos grupos de captura está disponível por seus números, precedidos por uma barra invertida. Por exemplo, o grupo zero estará disponível assim: \0, o primeiro grupo assim - \1, o segundo - \2 e assim por diante.

Estou certo de que tudo escrito acima ainda está bastante nebuloso para você. Isso não é surpreendente, pois os grupos de captura são o aspecto menos compreendido das expressões regulares. Vamos entender com exemplos.

Exemplo

Suponha que temos a seguinte string:

php<?php
  $str = 'aa bb cd ef';
?>

Vamos encontrar todos os lugares onde existem duas letras iguais consecutivas. Para resolver o problema, vamos procurar qualquer letra, colocá-la em um grupo de captura e, em seguida, verificar se o próximo caractere é o conteúdo desse grupo:

php<?php
  $res = preg_replace('#([a-z])\1#', '!', $str);
?>

Como resultado, o seguinte será armazenado na variável:

php'! ! cd ef'

Exemplo

Suponha que temos a seguinte string:

php<?php
  $str = 'asxca buzxb csgd';
?>

Vamos encontrar todas as palavras em que a primeira e a última letras são iguais. Para resolver o problema, escreveremos o seguinte padrão: uma letra, seguida por uma ou mais letras, e depois a mesma letra que a primeira:

php<?php
  $res = preg_replace('#([a-z])[a-z]+\1#', '!', $str);
?>

Como resultado, o seguinte será armazenado na variável:

php'! ! csgd'

Exemplo

Em vez de \1, pode-se escrever \g1:

php<?php
  $res = preg_replace('#([a-z])[a-z]+\g1#', '!', $str);
?>

Exemplo

Também é possível escrever \g{1}:

php<?php
  $res = preg_replace('#([a-z])[a-z]+\g{1}#', '!', $str);
?>

Exemplo

Em chaves, números negativos podem ser especificados. Neste caso, os grupos de captura serão contados a partir do final:

php<?php
  $res = preg_replace('#([a-z])([a-z])\g{-2}#', '!', $str);
?>

Problemas práticos

Задание 1

Dada a string:

php<?php
  $str = 'aaa bbb ccc xyz';
?>

Encontre todas as substrings que contêm três letras iguais consecutivas.

Задание 2

Dada a string:

php<?php
  $str = 'a aa aaa abab bbbb';
?>

Encontre todas as substrings que contêm duas ou mais letras iguais consecutivas.

Задание 3

Dada a string:

php<?php
  $str = 'aaa aaa bbb bbb ccc ddd';
?>

Encontre todas as substrings que contêm duas palavras iguais consecutivas.