Grupos de captura en expresiones regulares en PHP
El contenido de los grupos de captura está disponible no solo en la cadena de reemplazo, sino también en la propia expresión regular: podemos guardar algo en un grupo de captura y luego directamente en la expresión regular indicar que aquí debe estar el contenido de ese grupo de captura.
El contenido de los grupos de captura está disponible por sus números,
precedidos por una barra invertida. Por ejemplo,
el grupo de captura cero estará disponible así: \0,
el primer grupo de captura así - \1, el segundo
- \2 y así sucesivamente.
Estoy seguro de que todo lo escrito arriba todavía es bastante confuso para ti. No es de extrañar, ya que los grupos de captura son el lugar menos comprendido de las expresiones regulares. Vamos a entenderlo con ejemplos.
Ejemplo
Supongamos que tenemos la siguiente cadena:
<?php
$str = 'aa bb cd ef';
?>
Encontremos en ella todos los lugares donde hay dos letras iguales seguidas. Para resolver el problema, buscaremos cualquier letra, la guardaremos en un grupo de captura, y luego verificaremos si el siguiente carácter es el contenido de ese grupo de captura:
<?php
$res = preg_replace('#([a-z])\1#', '!', $str);
?>
Como resultado, en la variable se guardará lo siguiente:
'! ! cd ef'
Ejemplo
Supongamos que tenemos la siguiente cadena:
<?php
$str = 'asxca buzxb csgd';
?>
Encontremos en ella todas las palabras en las que la primera y la última letra son iguales. Para resolver el problema, escribiremos el siguiente patrón: letra, luego una o más letras más, y luego la misma letra que la primera:
<?php
$res = preg_replace('#([a-z])[a-z]+\1#', '!', $str);
?>
Como resultado, en la variable se guardará lo siguiente:
'! ! csgd'
Ejemplo
En lugar de \1 se puede escribir \g1:
<?php
$res = preg_replace('#([a-z])[a-z]+\g1#', '!', $str);
?>
Ejemplo
También se puede escribir \g{1}:
<?php
$res = preg_replace('#([a-z])[a-z]+\g{1}#', '!', $str);
?>
Ejemplo
En las llaves se pueden indicar números negativos. En este caso, los grupos de captura se contarán desde el final:
<?php
$res = preg_replace('#([a-z])([a-z])\g{-2}#', '!', $str);
?>
Problemas prácticos
Dada la cadena:
<?php
$str = 'aaa bbb ccc xyz';
?>
Encuentra todas las subcadenas en las que hay tres letras iguales seguidas.
Dada la cadena:
<?php
$str = 'a aa aaa abab bbbb';
?>
Encuentra todas las subcadenas en las que hay dos o más letras iguales seguidas.
Dada la cadena:
<?php
$str = 'aaa aaa bbb bbb ccc ddd';
?>
Encuentra todas las subcadenas en las que hay dos palabras iguales seguidas.