preg_match($pattern, $subject, $matches) comprueba si una cadena coincide con una expresión regular. Devuelve 1 si hay coincidencia y 0 si no, y rellena $matches con lo que encontró: preg_match('/\d+/', 'Order 4521 shipped', $m) devuelve 1 y pone $m[0] a "4521".
El patrón es una cadena con delimitadores alrededor, normalmente /.../, seguida de modificadores como i. Escribe los patrones entre comillas simples: dentro de comillas dobles PHP expande primero $name y secuencias de escape como \x41 o \101, así que el motor de expresiones regulares puede recibir un patrón distinto del que escribiste.
Grupos de captura
Los paréntesis de un patrón capturan la parte de la cadena con la que coinciden. $m[0] es la coincidencia completa, $m[1] el primer grupo y $m[2] el segundo, contados por el paréntesis de apertura desde la izquierda.
Grupos con nombre
(?<name>...) le da un nombre a un grupo. El valor se guarda bajo el nombre y bajo su número, así que el código que lee el resultado no se rompe cuando alguien añade un grupo antes en el patrón.
Encontrar todas las coincidencias con preg_match_all
preg_match_all() sigue buscando tras la primera coincidencia y devuelve el número de coincidencias. Por defecto, $m[0] contiene todas las coincidencias completas y $m[1] todos los valores del primer grupo. Con PREG_SET_ORDER obtienes en su lugar un array por coincidencia, más fácil de recorrer.
Validar entradas: anclajes, teléfonos, códigos postales
Para validar, el patrón debe coincidir con la cadena completa, así que empiézalo con ^ y termínalo con $. Una trampa: $ también coincide antes de un salto de línea final, así que '/^\d+$/' acepta "123\n". Añade el modificador D, o usa \z, que solo coincide justo al final.
Con las direcciones de email, una expresión regular o rechaza direcciones válidas o acepta inválidas. Usa en su lugar filter_var($email, FILTER_VALIDATE_EMAIL) (consulta filter_var()).
El modificador u para UTF-8 y texto japonés
Sin el modificador u, un patrón trabaja con bytes. Un carácter japonés ocupa tres bytes en UTF-8, así que . coincide con un tercio de carácter y las longitudes salen mal. Con u, el patrón trabaja con caracteres y puedes usar clases de propiedades Unicode.
u también valida la cadena: si no es UTF-8 válido, preg_match() devuelve false en lugar de buscar coincidencias.
Escapar la entrada del usuario con preg_quote
Caracteres como ., +, ?, ( y / tienen significados especiales en un patrón. Si parte del patrón viene de una variable, como un término de búsqueda, pásala por preg_quote() con el delimitador como segundo argumento, o 1+1 coincidirá con 11 y una / sin escapar romperá el patrón.
Un patrón no válido no lanza una excepción. PHP imprime un warning y preg_match() devuelve false:
Warning: preg_match(): No ending delimiter '/' found in /path/to/index.php on line 3
Así que comprueba === false (o preg_last_error_msg()) cuando el patrón se construye en tiempo de ejecución. Para comprobar una subcadena simple sin ningún patrón, str_contains() es más rápido y más claro. Para cambiar el texto encontrado, usa preg_replace().
Preguntas frecuentes
¿Qué devuelve preg_match en PHP?
1 si el patrón coincide, 0 si no, y false si el propio patrón no es válido. Como 0 y false son los dos falsy, compara con === 1 cuando necesites distinguir un patrón fallido de una ausencia de coincidencia.
¿Cómo obtengo el texto encontrado con preg_match?
Pasa un tercer argumento: preg_match('/(\d+)/', 'Order 4521', $m). Entonces $m[0] es la coincidencia completa y $m[1] el primer grupo de captura, los dos "4521" aquí. Con un grupo con nombre (?<id>\d+) el valor también está en $m['id'].
¿Cuál es la diferencia entre preg_match y preg_match_all?
preg_match() se detiene en la primera coincidencia. preg_match_all() encuentra todas las coincidencias, devuelve cuántas encontró y rellena $matches con todas ellas: preg_match_all('/\d+/', 'a1 b22 c333', $m) devuelve 3 y $m[0] es ["1", "22", "333"].
¿Cómo uso preg_match con japonés u otro texto UTF-8?
Añade el modificador u: preg_match('/^.{3}$/u', '日本語') devuelve 1. Sin u, PHP trata la cadena como bytes, así que . coincide con un byte de un carácter de 3 bytes. Con u también puedes usar clases Unicode como \p{Han}, \p{Hiragana} y \p{Katakana}.
¿Cómo compruebo si una cadena contiene solo números en PHP?
preg_match('/^\d+$/D', $s) o, sin expresión regular, ctype_digit($s). El modificador D (o \z en lugar de $) importa: un $ simple también acepta un salto de línea final, así que "123\n" pasaría.