W3docs

preg_match_all()

En PHP, preg_match_all() realiza una búsqueda global con expresiones regulares y devuelve todas las coincidencias encontradas en una cadena.

Introducción

En PHP, las expresiones regulares son esenciales para buscar y manipular cadenas. Mientras que preg_match() se detiene en la primera coincidencia, preg_match_all() continúa analizando y devuelve cada ocurrencia de un patrón en una cadena. Úsala cuando necesites extraer todos los números de teléfono, todas las etiquetas, todas las palabras o cualquier estructura repetitiva de un texto.

Este artículo explica la sintaxis, el importante argumento $flags que controla cómo se organizan los resultados, y varios ejemplos prácticos.

Sintaxis

preg_match_all(
    string $pattern,
    string $subject,
    array &$matches = null,
    int $flags = PREG_PATTERN_ORDER,
    int $offset = 0
): int|false
  • $pattern — la expresión regular, delimitada por /.../ (o cualquier par de delimitadores coincidentes).
  • $subject — la cadena en la que buscar.
  • $matches — un array de salida (pasado por referencia) que se rellena con todas las coincidencias encontradas.
  • $flags — opcional. Controla cómo se estructura $matches (ver más abajo).
  • $offset — opcional. Desplazamiento en bytes dentro de $subject desde el cual comenzar la búsqueda.

Devuelve el número de coincidencias completas del patrón (que puede ser 0), o false si el patrón no es válido.

Una coincidencia simple

El uso más básico es recopilar cada subcadena que coincida con un patrón. Aquí extraemos todos los números de una oración:

<?php

$subject = 'Room 12, floor 3, building 7';

$count = preg_match_all('/\d+/', $subject, $matches);

echo "Found $count numbers\n";
print_r($matches[0]);

Salida:

Found 3 numbers
Array
(
    [0] => 12
    [1] => 3
    [2] => 7
)

Cuando el patrón no tiene grupos de captura, $matches[0] contiene la lista de coincidencias completas.

Elegir un indicador: PREG_PATTERN_ORDER vs PREG_SET_ORDER

El argumento $flags decide cómo se organizan las coincidencias y los grupos de captura. Los dos indicadores principales son mutuamente excluyentes:

  • PREG_PATTERN_ORDER (el valor predeterminado) — $matches[0] contiene todas las coincidencias completas, $matches[1] contiene todas las capturas del grupo 1, $matches[2] contiene todas las capturas del grupo 2, y así sucesivamente. Piénsalo como "columna por columna".
  • PREG_SET_ORDER$matches[0] es la primera coincidencia completa (coincidencia completa + sus grupos), $matches[1] es la segunda, y así sucesivamente. Piénsalo como "fila por fila".

También puedes añadir PREG_OFFSET_CAPTURE para registrar el desplazamiento en bytes de cada coincidencia junto a su texto.

PREG_SET_ORDER (agrupar resultados por ocurrencia)

Esta disposición es la más fácil de recorrer en bucle cuando cada coincidencia tiene varios grupos de captura:

php— editable, runs on the server

Salida:

Name: Alice, Age: 25
Name: Bob, Age: 30

Con PREG_SET_ORDER, cada $match es una ocurrencia: $match[0] es la coincidencia completa, $match[1] es el primer grupo (nombre), $match[2] es el segundo grupo (edad).

PREG_PATTERN_ORDER (agrupar resultados por patrón)

El mismo patrón con el indicador predeterminado devuelve los grupos como arrays paralelos:

<?php

$pattern = '/([A-Z][a-z]+) (\d+)/';
$subject = 'Alice 25 Bob 30';

preg_match_all($pattern, $subject, $matches, PREG_PATTERN_ORDER);

print_r($matches[1]); // all names
print_r($matches[2]); // all ages

Salida:

Array
(
    [0] => Alice
    [1] => Bob
)
Array
(
    [0] => 25
    [1] => 30
)

Grupos de captura con nombre

Nombrar los grupos con (?<nombre>...) hace que el resultado sea autodocumentado — los nombres se convierten en claves del array (junto con los índices numéricos):

<?php

$pattern = '/(?<name>[A-Z][a-z]+) (?<age>\d+)/';
$subject = 'Alice 25 Bob 30';

preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);

foreach ($matches as $match) {
  echo "{$match['name']} is {$match['age']}\n";
}

Salida:

Alice is 25
Bob is 30

Errores comunes

  • Verifica el valor de retorno, no el array. Un patrón puede no tener coincidencias y aun así ejecutarse correctamente; preg_match_all() devuelve 0, mientras que false indica que la expresión regular no es válida. Usa === false para detectar errores. Consulta preg_last_error() para conocer el motivo específico del fallo.
  • $matches se sobreescribe. Cada llamada reemplaza el contenido anterior del array de salida.
  • Elige el indicador adecuado para tu bucle. Usa PREG_SET_ORDER cuando quieras una fila por coincidencia; usa el valor predeterminado PREG_PATTERN_ORDER cuando quieras una columna por grupo.
  • Escapa los caracteres especiales en patrones dinámicos con preg_quote() cuando el patrón proviene de la entrada del usuario.

Conclusión

preg_match_all() devuelve todas las coincidencias de un patrón en una cadena, convirtiéndola en la función ideal para extraer datos repetitivos. La clave para usarla correctamente es comprender el argumento $flags: PREG_SET_ORDER agrupa los resultados por ocurrencia, mientras que el valor predeterminado PREG_PATTERN_ORDER los agrupa por grupo de captura.

Para herramientas relacionadas, consulta preg_match() para una sola coincidencia, preg_replace() para buscar y reemplazar, y preg_split() para dividir cadenas por un patrón.

Práctica

Práctica
¿Cuál es el propósito de la función preg_match_all() en PHP?
¿Cuál es el propósito de la función preg_match_all() en PHP?
Was this page helpful?