preg_replace_callback
Aprende a usar preg_replace_callback() en PHP para realizar búsquedas y reemplazos con expresiones regulares usando funciones de devolución de llamada.
Introducción
preg_replace_callback() realiza una búsqueda y reemplazo con expresión regular, pero en lugar de proporcionar una cadena de reemplazo fija, se le pasa una función de devolución de llamada que se ejecuta para cada coincidencia. La función de devolución recibe la coincidencia (y los grupos de captura) y devuelve el texto a sustituir. Esto permite calcular reemplazos con lógica real de PHP — poner una palabra en mayúsculas, sumar 1 a un número, buscar un valor en una tabla — algo que la función preg_replace() simple no puede hacer.
Úsala cuando el reemplazo dependa de lo que se encontró. Si el reemplazo es constante o una referencia inversa simple como $1, usa preg_replace(); si necesitas una devolución de llamada diferente por patrón, consulta preg_replace_callback_array().
Sintaxis
preg_replace_callback(
string|array $pattern,
callable $callback,
string|array $subject,
int $limit = -1,
int &$count = null,
int $flags = 0
): string|array|null| Parámetro | Descripción |
|---|---|
$pattern | La expresión regular (una cadena delimitada) a buscar, o un array de patrones. |
$callback | Un callable que se ejecuta para cada coincidencia. Recibe el array de coincidencias y devuelve la cadena de reemplazo. |
$subject | La cadena (o array de cadenas) en la que buscar y modificar. |
$limit | Número máximo de reemplazos por cadena de sujeto. -1 (el valor predeterminado) significa sin límite. |
$count | Pasado por referencia; se rellena con el número de reemplazos realizados. |
$flags | PREG_OFFSET_CAPTURE y/o PREG_UNMATCHED_AS_NULL, igual que en preg_match(). |
Devuelve el sujeto modificado, o null si ocurre un error en la expresión regular. El primer argumento de la devolución de llamada es el array $matches: $matches[0] es la coincidencia completa y $matches[1], $matches[2], … son los grupos capturados — exactamente como el array que rellena preg_match().
Ejemplo básico: convertir cada palabra a mayúsculas
El patrón \w+ coincide con cada secuencia de caracteres de palabra. Para cada coincidencia, la devolución de llamada recibe $matches[0] (la palabra) y devuelve su forma en mayúsculas, que se inserta de nuevo en la cadena.
Trabajar con grupos de captura
Los paréntesis en el patrón crean grupos de captura que aparecen en $matches[1], $matches[2], y así sucesivamente. Aquí sumamos uno a cada número en una cadena:
<?php
$subject = 'Room 12, floor 3, building 7';
$result = preg_replace_callback('/(\d+)/', function ($m) {
return (string) ((int) $m[1] + 1);
}, $subject);
echo $result;
// Room 13, floor 4, building 8Como la devolución de llamada ejecuta código real, el incremento se calcula por cada coincidencia — algo que una cadena de reemplazo estática nunca puede expresar.
Un caso de uso práctico: enmascarar datos sensibles
Una tarea habitual es ocultar parcialmente correos electrónicos o números de tarjeta en registros. La devolución de llamada puede decidir cuánto de cada coincidencia revelar:
<?php
$text = 'Contact: [email protected] or [email protected]';
$result = preg_replace_callback('/([\w.]+)@([\w.]+)/', function ($m) {
$name = $m[1];
$masked = $name[0] . str_repeat('*', max(strlen($name) - 1, 1));
return $masked . '@' . $m[2];
}, $text);
echo $result;
// Contact: a****@example.com or b**@test.orgContar y limitar reemplazos
Los parámetros $limit y $count permiten limitar cuántas coincidencias se procesan y saber cuántas se realizaron:
<?php
$subject = 'a a a a a';
$result = preg_replace_callback('/a/', function ($m) {
return 'b';
}, $subject, 2, $count);
echo $result, "\n"; // b b a a a
echo $count; // 2Solo se reemplazan las dos primeras a porque $limit es 2, y $count reporta el número de reemplazos realizados.
preg_replace vs. preg_replace_callback
| Uso | Función |
|---|---|
Texto fijo o una referencia inversa como $1 | preg_replace() |
| Reemplazo calculado a partir de la coincidencia | preg_replace_callback() |
| Una devolución de llamada diferente por patrón | preg_replace_callback_array() |
Para buscar sin reemplazar, consulta preg_match() y preg_match_all(), y el capítulo de expresiones regulares en PHP para la sintaxis de patrones.
Errores comunes
- Siempre devuelve una cadena. El valor de retorno de la devolución de llamada se convierte en cadena y se inserta. Devolver
nullelimina la coincidencia; olvidar elreturninserta una cadena vacía. - Referencia el índice correcto.
$matches[0]es la coincidencia completa; el grupo 1 está en$matches[1]. Un error de desplazamiento aquí es el fallo más frecuente. - Escapa con cuidado. A diferencia de
preg_replace(), no se escriben referencias inversas$1/\1en el resultado — construyes la cadena tú mismo, por lo que no hay nada que escapar en el reemplazo. - Un valor de retorno
nullde la propia función (no de la devolución de llamada) indica un error en la expresión regular, como un delimitador sin cerrar.
Conclusión
preg_replace_callback() es la herramienta adecuada cuando un reemplazo debe calcularse en lugar de definirse de forma estática. Combina el poder de búsqueda de las expresiones regulares con lógica PHP arbitraria en la devolución de llamada, lo que la hace ideal para transformar, enmascarar o recalcular texto coincidente. Para reemplazos estáticos, usa preg_replace(), y para varios patrones a la vez, usa preg_replace_callback_array().