preg_grep()
Aprende a usar preg_grep() en PHP para filtrar arrays usando expresiones regulares, con ejemplos de uso básico e invertido.
Introducción
preg_grep() filtra un array y conserva únicamente los elementos que coincidan (o, de forma opcional, que no coincidan) con una expresión regular. Es el miembro orientado a arrays de la familia PCRE de PHP: en lugar de probar una cadena individual como preg_match(), recorre cada elemento de un array y devuelve un nuevo array con los elementos que superan la prueba.
Esta página cubre la firma y los parámetros de la función, la diferencia entre la coincidencia normal y la invertida, el comportamiento de las claves devueltas, casos de uso reales habituales y las trampas a tener en cuenta.
Sintaxis
preg_grep(string $pattern, array $array, int $flags = 0): array|falseLa función acepta tres parámetros:
$pattern— un patrón PCRE, escrito como una cadena con delimitadores (p. ej./^g/,~\d+~,#error#i).$array— el array de entrada a filtrar. Solo se evalúan sus valores, nunca sus claves.$flags(opcional) — pasa la constantePREG_GREP_INVERTpara devolver los elementos que no coincidan. Por defecto es0(devuelve los elementos que coinciden).
Devuelve un nuevo array con los elementos coincidentes, preservando las claves originales. Si el patrón no es válido, devuelve false y emite una advertencia.
Ejemplo básico
preg_grep() recorre el array y conserva cada valor que coincide con el patrón. En este ejemplo conservamos solo los colores que comienzan con la letra g:
Salida:
Array
(
[2] => green
)Observa la clave: green estaba en el índice 2 del array de entrada, y preg_grep() conserva esa clave en el resultado. El array devuelto, por tanto, no se reindexa — si necesitas claves secuenciales, envuelve la llamada en array_values().
Filtrado con PREG_GREP_INVERT
Pasa PREG_GREP_INVERT como tercer argumento para invertir la lógica: obtendrás los elementos que no pasan el patrón. Esto es muy útil para tareas del tipo "eliminar las entradas incorrectas". Aquí eliminamos todas las cadenas que contienen un dígito:
<?php
$entries = ["apple1", "banana", "cherry7", "date", "fig2"];
$result = preg_grep("/[0-9]/", $entries, PREG_GREP_INVERT);
print_r($result);Salida:
Array
(
[1] => banana
[3] => date
)Solo banana y date sobreviven porque no contienen dígitos — y de nuevo se preservan sus claves originales (1 y 3).
Casos de uso prácticos
Filtrar líneas de log por nivel
Una tarea habitual es extraer solo las líneas de error de una lista de entradas de log. Un patrón anclado sensible a mayúsculas lo mantiene preciso:
<?php
$logs = [
"INFO ok",
"ERROR disk full",
"WARN low mem",
"ERROR timeout",
];
$errors = preg_grep("/^ERROR/", $logs);
print_r($errors);Salida:
Array
(
[1] => ERROR disk full
[3] => ERROR timeout
)Conservar solo cadenas completamente numéricas
Al validar una entrada mixta, preg_grep() permite conservar solo los valores que coincidan con una forma estricta en una sola línea. Los anclajes ^\d+$ garantizan que la cadena completa sea de dígitos:
<?php
$mixed = ["12", "ab", "3x", "99"];
$nums = preg_grep("/^\d+$/", $mixed);
print_r($nums);Salida:
Array
(
[0] => 12
[3] => 99
)Trampas y consejos
- Las claves se preservan, no se reinician. Como se muestra arriba, los huecos en las claves del resultado son normales. Usa
array_values()si necesitas0, 1, 2, …. - Solo se evalúan los valores.
preg_grep()ignora completamente las claves del array — no existe una variante basada en claves. - Los patrones no válidos devuelven
false, no un array vacío. Valida siempre el tipo del resultado si el patrón proviene de la entrada del usuario:if ($result === false) { /* bad pattern */ }. - No modifica la entrada. Como la mayoría de los helpers de arrays de PHP, devuelve un nuevo array y deja
$arraysin cambios. - Los valores no string se convierten. Los números y otros escalares se convierten a string antes de la comparación, por lo que
preg_grep("/^1/", [10, 20])coincide con10.
Funciones relacionadas
preg_match()— comprueba una cadena individual contra un patrón.preg_match_all()— encuentra todas las coincidencias dentro de una cadena.preg_replace()— busca y reemplaza usando un patrón.preg_split()— divide una cadena en un array mediante un patrón.preg_filter()— comopreg_replace()pero devuelve solo los sujetos que coinciden.
Conclusión
preg_grep() es la forma más limpia de filtrar un array con una expresión regular en PHP. Úsala sola para conservar los elementos coincidentes, añade PREG_GREP_INVERT para eliminarlos, y recuerda que preserva las claves originales. Para comparar una sola cadena usa preg_match(); para reemplazar usa preg_replace().