W3docs

preg_last_error()

Aprende cómo preg_last_error() de PHP informa el código de error de la última llamada PCRE, con constantes de error, preg_last_error_msg() y ejemplos.

Introducción

Las expresiones regulares son una herramienta poderosa para manipular y buscar cadenas en PHP. En ocasiones, las operaciones de regex fallan debido a patrones inválidos o límites del motor. La función preg_last_error() ayuda a identificar estos fallos devolviendo el código de error de la última llamada a una función PCRE.

Sintaxis

preg_last_error(): int

La función no recibe argumentos. Devuelve una constante entera que describe qué salió mal durante la última llamada a una función PCRE — como preg_match(), preg_match_all(), preg_replace() o preg_split(). Si la última llamada tuvo éxito, devuelve PREG_NO_ERROR (0).

Por qué la necesitas

Las funciones PCRE son inusuales: cuando fallan, no lanzan una excepción. En cambio, preg_match() devuelve false (no 0 — eso significa "sin coincidencia"), y preg_replace() devuelve null. Estos valores de retorno te indican que algo falló, pero no por qué. preg_last_error() llena ese vacío informando la razón subyacente.

Por eso debes comparar con === en lugar de un == flexible: 0 (sin coincidencia) y false (error) ambos parecen "falsy", pero significan cosas muy distintas.

Constantes de error

preg_last_error() devuelve una de estas constantes enteras. Los valores numéricos se muestran como referencia, pero siempre debes comparar contra la constante con nombre.

ConstanteValorSignificado
PREG_NO_ERROR0Sin error — la última operación tuvo éxito.
PREG_INTERNAL_ERROR1Un error interno de PCRE (generalmente un patrón malformado).
PREG_BACKTRACK_LIMIT_ERROR2El patrón alcanzó el límite pcre.backtrack_limit.
PREG_RECURSION_LIMIT_ERROR3El patrón alcanzó el límite pcre.recursion_limit.
PREG_BAD_UTF8_ERROR4El sujeto no es UTF-8 válido (con el modificador u).
PREG_BAD_UTF8_OFFSET_ERROR5El desplazamiento no coincidió con el inicio de un punto de código UTF-8 válido.
PREG_JIT_STACKLIMIT_ERROR6El patrón agotó el límite de pila JIT.

Desde PHP 8.0, preg_last_error_msg() devuelve la misma información como una cadena legible por humanos, lo cual es útil para registros de log.

Provocar y leer un error

Un fallo común en la práctica es el retroceso catastrófico, donde un patrón mal escrito obliga al motor a intentar una cantidad enorme de caminos y supera el límite de retroceso. El siguiente ejemplo reduce pcre.backtrack_limit para que el fallo sea reproducible y luego examina el resultado.

<?php

// Lower the limit so the failure is easy to reproduce.
ini_set('pcre.backtrack_limit', '100');

$pattern = '/(\w+)*$/';            // nested quantifier — backtracks heavily
$string  = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!';

$result = preg_match($pattern, $string, $matches);

if ($result === false) {
    echo 'preg_match() failed!' . PHP_EOL;
    echo 'Error code: ' . preg_last_error() . PHP_EOL;
    echo 'Error message: ' . preg_last_error_msg() . PHP_EOL;

    if (preg_last_error() === PREG_BACKTRACK_LIMIT_ERROR) {
        echo 'The pattern was too expensive to evaluate.' . PHP_EOL;
    }
} elseif ($result === 1) {
    echo 'Match found.' . PHP_EOL;
} else {
    echo 'No match.' . PHP_EOL;
}

Salida:

preg_match() failed!
Error code: 2
Error message: Backtrack limit exhausted
The pattern was too expensive to evaluate.

El código de error 2 corresponde a PREG_BACKTRACK_LIMIT_ERROR. De manera crucial, la verificación if ($result === false) es la que nos indica que ocurrió un error real — un 0 aquí simplemente significaría que el patrón no coincidió.

Detectar entradas UTF-8 inválidas

Cuando usas el modificador u (unicode) en una cadena que no es UTF-8 válido, PCRE falla y establece PREG_BAD_UTF8_ERROR:

<?php

$result = preg_match('/./u', "\x80");   // \x80 is not a valid UTF-8 sequence

if ($result === false && preg_last_error() === PREG_BAD_UTF8_ERROR) {
    echo 'Invalid UTF-8 input: ' . preg_last_error_msg();
}
// Invalid UTF-8 input: Malformed UTF-8 characters, possibly incorrectly encoded

Esta es una fuente frecuente de errores silenciosos al procesar datos enviados por el usuario, por lo que protegerse contra esto es una buena práctica.

Errores comunes

  • Compruébalo inmediatamente. preg_last_error() refleja solo la llamada PCRE más reciente. Cualquier llamada posterior a una regex lo sobreescribirá, así que léelo justo después de la operación que te interesa.
  • false vs 0. Usa siempre ===. preg_match() devuelve 0 para "sin coincidencia" y false para un error — no son intercambiables.
  • Fallos de preg_replace(). Cuando preg_replace() devuelve null, también vale la pena llamar a preg_last_error() para saber por qué.

Conclusión

preg_last_error() convierte un false opaco en una razón concreta, lo que lo hace imprescindible para depurar expresiones regulares en PHP. Al comparar los valores de retorno con === e inspeccionar el código de error (o preg_last_error_msg()), puedes distinguir claramente entre fallos del motor y simples ausencias de coincidencia. Para las funciones cuyos fallos reporta, consulta preg_match(), preg_replace() y preg_split().

Práctica

Práctica
¿Qué hace la función 'preg_last_error' en PHP?
¿Qué hace la función 'preg_last_error' en PHP?
Was this page helpful?