W3docs

Expresiones Regulares en PHP

Aprende a usar expresiones regulares en PHP con las funciones preg_ para validar, extraer y reemplazar texto mediante patrones.

Una expresión regular (regex) es un patrón que describe un conjunto de cadenas. En lugar de buscar un fragmento de texto fijo, describes su forma — "una dirección de correo electrónico", "una secuencia de dígitos", "una palabra que termina en .php" — y PHP encuentra, valida, reemplaza o divide texto que coincida.

Este capítulo explica cómo funcionan las funciones preg_ de PHP, la sintaxis de un patrón (delimitadores, clases de caracteres, cuantificadores, grupos, anclas) y las tareas prácticas más habituales: validar entradas, extraer datos y reemplazar texto.

Qué son las expresiones regulares

Una expresión regular es una secuencia de caracteres que define un patrón de búsqueda. La mayoría de los caracteres se corresponden consigo mismos — el patrón cat coincide con el texto literal cat. El poder proviene de los metacaracteres, que representan categorías de caracteres o repeticiones:

TokenSignificadoEjemplo de coincidencia
.Cualquier carácter individual (excepto salto de línea)c.tcat, cut
\dUn dígito 0-9\d\d42
\wUn carácter "de palabra" (a-z, A-Z, 0-9, _)\w+hello_1
\sEspacio en blanco (espacio, tabulación, salto de línea)
[abc]Cualquiera de a, b, c[aeiou]e
[^abc]Cualquier carácter excepto a, b, c
a*Cero o más a"", aaa
a+Una o más aa, aaa
a?Cero o una a (opcional)"", a
a{2,4}Entre 2 y 4 de aaa, aaaa
^ / $Inicio / fin de la cadena
|Alternancia ("o")cat|dogcat o dog
()Agrupación / captura(ab)+abab

Cómo funcionan las expresiones regulares en PHP

PHP utiliza PCRE (Expresiones Regulares Compatible con Perl) a través de la familia de funciones preg_. Las más utilizadas son:

FunciónQué hace
preg_match()Comprueba si un patrón coincide; captura la primera coincidencia
preg_match_all()Encuentra todas las coincidencias en una cadena
preg_replace()Reemplaza cada coincidencia con nuevo texto
preg_split()Divide una cadena según un patrón
preg_quote()Escapa los metacaracteres de regex en una cadena literal

La sintaxis de un patrón PHP

Un patrón PHP es una cadena compuesta de tres partes: un delimitador, el patrón y modificadores opcionales.

/pattern/modifiers

El primer carácter es el delimitador — casi siempre /, pero cualquier carácter no alfanumérico funciona (#, ~, !). Elegir un delimitador que no aparezca en el patrón evita tener que escaparlo. Por ejemplo, hacer coincidir una ruta URL es más limpio con #:

"#^/users/\d+$#"   // no need to escape the slashes

Los modifiers son letras opcionales tras el delimitador de cierre que cambian el comportamiento del motor:

  • iinsensible a mayúsculas: /php/i coincide con PHP, Php, php.
  • mmultilínea: ^ y $ coinciden al inicio/fin de cada línea, no solo de toda la cadena.
  • ssingle line ("dotall"): . también coincide con saltos de línea.
  • u — trata el patrón y el texto como UTF-8. Úsalo con cualquier texto que contenga caracteres no ASCII.
  • x — extendido: los espacios en blanco del patrón se ignoran, permitiendo espaciar y comentar patrones complejos.

Comprobar una coincidencia con preg_match

preg_match() devuelve 1 si el patrón se encuentra, 0 si no, y false en caso de error. Es la opción adecuada para una pregunta de sí/no como "¿contiene esta cadena un dígito?"

php— editable, runs on the server

El tercer argumento opcional, $matches, se rellena con los resultados: $matches[0] es la coincidencia completa, y $matches[1], $matches[2], … son los grupos de captura en orden — las subcadenas capturadas por cada par de paréntesis.

Validar la entrada del usuario

Un uso habitual de las regex es validar la entrada del usuario — comprobar que un valor tiene la forma correcta antes de almacenarlo o confiar en él. Aquí tienes una comprobación básica de correo electrónico:

<?php

$email = "[email protected]";

if (preg_match("/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/", $email)) {
    echo "Valid email address";
} else {
    echo "Invalid email address";
}

?>

Las anclas ^ y $ son importantes aquí: sin ellas, el patrón coincidiría con un correo electrónico dentro de una cadena más grande, por lo que "junk [email protected] junk" pasaría la validación. Con ellas, toda la cadena debe ser un único correo electrónico.

Para el correo electrónico específicamente, el filter_var() integrado de PHP con FILTER_VALIDATE_EMAIL es más robusto que una regex escrita a mano. Recurre a las regex cuando necesites un formato que los filtros no cubran — códigos postales, IDs personalizados, formatos de teléfono. Consulta la validación de formularios PHP para ver un ejemplo completo de comprobación de entradas.

Encontrar todas las coincidencias con preg_match_all

Mientras que preg_match() se detiene en la primera coincidencia, preg_match_all() las recopila todas — útil para extraer cada hashtag, precio o enlace de un bloque de texto.

<?php

$text = "Prices: $12, $7 and $349";

preg_match_all("/\\\$(\d+)/", $text, $matches);

print_r($matches[1]); // the captured numbers

?>

$matches[1] contiene un array con cada grupo capturado — en este caso, ["12", "7", "349"].

Reemplazar texto con preg_replace

preg_replace() sustituye cada coincidencia. En la cadena de reemplazo, $1, $2, … hacen referencia a los grupos capturados, por lo que puedes reescribir además de eliminar:

<?php

$date = "2026-06-21";

// Reformat YYYY-MM-DD into DD/MM/YYYY
echo preg_replace("/(\d{4})-(\d{2})-(\d{2})/", "$3/$2/$1", $date);
// 21/06/2026

?>

Para dividir una cadena en partes según un patrón en lugar de reemplazarlo, usa preg_split() — por ejemplo, dividir en cualquier secuencia de espacios en blanco con /\s+/.

Técnicas avanzadas

Una vez que te sientas cómodo con los conceptos básicos, estas funcionalidades permiten manejar patrones más complejos:

  • Grupos de captura (...) — extrae partes específicas de una coincidencia, como se mostró anteriormente con $matches[1].
  • Grupos de no captura (?:...) — agrupa sin ocupar una posición en $matches, cuando solo necesitas la agrupación para un cuantificador o alternancia.
  • Grupos con nombre (?<year>\d{4}) — referencia una coincidencia por nombre ($matches['year']) en lugar de por número.
  • Lookahead (?=...) y lookbehind (?<=...) — coincide según lo que viene después o antes, sin consumirlo. Útil para "un número seguido de px" sin capturar px.
  • Cuantificadores perezosos *?, +? — coincide con el menor número posible de caracteres. Por defecto, .* es codicioso y captura todo lo que puede.

Una nota sobre el escape: caracteres como ., +, *, ?, (, ), [, \ tienen un significado especial. Para que coincidan literalmente, prefíjalos con una barra invertida (\. coincide con un punto literal). Cuando el texto literal proviene de una variable, usa preg_quote() para escaparlo de forma segura.

Errores comunes

  • Olvidar los delimitadores. Los patrones PHP son cadenas y deben incluir delimitadores: "/\d+/", no "\d+". Omitirlos genera un aviso y la coincidencia falla.
  • Doble escape en cadenas entre comillas dobles. Dentro de "...", una barra invertida es también un escape de PHP. "/\d/" funciona porque \d no es un escape de PHP, pero para coincidir con un $ literal necesitas "/\\$/". Las cadenas entre comillas simples ('/\d/') evitan esta sorpresa.
  • La coincidencia codiciosa captura demasiado. <.*> sobre <a><b> coincide con todo <a><b>, no solo con <a>. Usa un patrón perezoso <.*?> o una clase negada <[^>]*>.
  • Omitir el modificador u en UTF-8. Sin /u, . y \w operan sobre bytes, corrompiendo los caracteres multibyte.

Conclusión

Las expresiones regulares permiten describir la forma del texto en lugar de su contenido exacto, lo que las hace indispensables para validar entradas, extraer datos y transformar cadenas. En PHP las utilizas a través de las funciones preg_: preg_match() y preg_match_all() para buscar, preg_replace() para reescribir y preg_split() para dividir cadenas. Comienza con anclas, clases de caracteres y cuantificadores, y luego añade grupos y lookarounds a medida que tus patrones crezcan. Para profundizar en las cadenas con las que trabajarás, consulta PHP Strings.

Práctica

Práctica
¿Cuál es el propósito principal de las regex en PHP?
¿Cuál es el propósito principal de las regex en PHP?
Was this page helpful?