Reemplazo con callback mediante expresiones regulares en PHP
Supongamos que tenemos la siguiente cadena:
<?php
$str = '2+3= 3+5= 7+8=';
?>
Supongamos que necesitamos encontrar todas las construcciones de la forma número+número= y hacer que después del igual aparezca el resultado de la suma.
Para resolver esta tarea es conveniente usar
la función preg_replace_callback, que
funciona de manera similar a la función preg_replace
- encuentra y reemplaza usando una expresión regular,
pero permite realizar manipulaciones adicionales
con los fragmentos encontrados.
El primer parámetro de la función acepta la expresión regular, el segundo - por qué lo reemplazamos, el tercero - la cadena en la que se realiza el reemplazo.
En este caso, al segundo parámetro se le debe pasar una función callback, que será llamada para cada coincidencia encontrada.
Como primer parámetro del callback se debe especificar una variable, en la que llegará lo encontrado. Esta variable será un array de los grupos de captura (capturas) encontrados.
Probemos en la práctica. Escribamos el código que capture nuestras subcadenas, poniendo el primer número en el primer grupo de captura, y el segundo - en el segundo:
<?php
$str = '2+3= 3+5= 7+8=';
preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
var_dump($match);
}, $str);
?>
Como resultado, nuestro var_dump funcionará
tres veces, mostrando sucesivamente lo siguiente:
['2+3=', '2', '3']
['3+5=', '3', '5']
['7+8=', '7', '7']
Continuemos. Cada coincidencia será reemplazada
por lo que devuelva el callback mediante return.
Pongamos como ejemplo reemplazar cada una de las subcadenas
buscadas por el signo '!':
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return '!';
}, $str);
echo $res; // mostrará '! ! !'
?>
Y ahora reemplacemos cada subcadena por la suma del par de números en ella:
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return $match[1] + $match[2];
}, $str);
echo $res; // mostrará '5 8 13'
?>
Resulta que nuestra tarea está casi resuelta. Solo queda hacer que antes de la suma de los números permanezca la subcadena buscada. Para ello insertaremos antes de la suma el contenido del grupo de captura cero (la coincidencia completa):
<?php
$str = '2+3= 3+5= 7+8=';
$res = preg_replace_callback('#(\d+)\+(\d+)=#', function($match) {
return $match[0] . ($match[1] + $match[2]);
}, $str);
echo $res; // mostrará '2+3=5 3+5=8 7+8=13'
?>
Se da la cadena:
<?php
$str = 'The numbers are 3, 7 and 12';
?>
Reemplace todos los números en la cadena por sus cuadrados.
Resultado esperado:
'The numbers are 9, 49 and 144'
Se da la cadena:
<?php
$str = '2023-01-15 2022-12-31 2024-05-20';
?>
Convierta todas las fechas al formato día.mes.año.
Se da la cadena:
<?php
$str = 'Costs: $15, $20, $100';
?>
Aumente todos los precios en 10%.