Preg last error: примеры (PHP)

Функция preg_last_error: примеры использования и обработка ошибок
Раздел: Регулярные выражения
preg_last_error: int

Функция preg_last_error() возвращает код последней ошибки, возникшей при выполнении регулярного выражения с функциями PCRE (Perl Compatible Regular Expressions). Она не принимает аргументов.

Назначение и применение

Использование функции актуально после вызова preg_match(), preg_match_all(), preg_replace(), preg_split() и других функций семейства PCRE. Если операция с регулярным выражением завершилась неудачей, preg_last_error() позволяет получить числовой код ошибки для последующей обработки.

Возвращаемые значения

Функция возвращает одну из предопределенных констант:

  • PREG_NO_ERROR (0) – ошибки отсутствуют.
  • PREG_INTERNAL_ERROR (1) – внутренняя ошибка PCRE.
  • PREG_BACKTRACK_LIMIT_ERROR (2) – превышен лимит обратного хода.
  • PREG_RECURSION_LIMIT_ERROR (3) – превышен лимит рекурсии.
  • PREG_BAD_UTF8_ERROR (4) – получена некорректная UTF-8 строка.
  • PREG_BAD_UTF8_OFFSET_ERROR (5) – смещение не соответствует корректному символу UTF-8.
  • PREG_JIT_STACKLIMIT_ERROR (6) – произошел отказ JIT-компилятора из-за нехватки памяти.
Базовый пример проверки ошибки
<?php
$result = preg_match('/[a-z', 'test'); // Некорректный шаблон
if ($result === false) {
    $errorCode = preg_last_error();
    echo "Код ошибки: $errorCode";
}
Код ошибки: 2
Пример с обработкой конкретной ошибки
<?php
$string = "Valid string";
$pattern = '/^(\w+\s*)+$/';
// Имитация backtrack limit для длинной строки
ini_set('pcre.backtrack_limit', 10);
$result = @preg_match($pattern, str_repeat($string, 1000));

if ($result === false) {
    switch(preg_last_error()) {
        case PREG_BACKTRACK_LIMIT_ERROR:
            echo "Превышен лимит обратного хода";
            break;
        case PREG_RECURSION_LIMIT_ERROR:
            echo "Превышен лимит рекурсии";
            break;
        default:
            echo "Произошла другая ошибка: " . preg_last_error();
    }
}
Превышен лимит обратного хода

В PHP 8.0 появилась функция preg_last_error_msg(), которая возвращает текстовое описание последней ошибки PCRE. Она более удобна, так как не требует расшифровки кодов ошибок.

<?php
preg_match('/[a-z', 'test');
echo preg_last_error_msg();
Backtrack limit exhausted

Для отладки регулярных выражений также полезны функции:

  • preg_match() с флагом PREG_OFFSET_CAPTURE – помогает найти позицию ошибки.
  • preg_grep() – возвращает массив совпадений, но не предоставляет детальной информации об ошибках.

Использование preg_last_error_msg() предпочтительнее в новых проектах на PHP 8+, так как упрощает обработку ошибок.

Игнорирование проверки возвращаемого значения
<?php
preg_match('/[a-z/', 'test');
// Ошибка: отсутствует проверка на false перед вызовом preg_last_error()
$error = preg_last_error(); // Всегда возвращает код, даже если ошибки не было
Неправильная интерпретация кодов ошибок
<?php
$result = preg_match('/\d+/', 'abc');
if ($result === 0) {
    // Это не ошибка, а отсутствие совпадений
    $error = preg_last_error(); // Вернет PREG_NO_ERROR (0)
    echo "Ошибка: $error"; // Неправильная трактовка
}
Ошибка: 0
Ошибки при работе с UTF-8
<?php
// Отсутствие модификатора u для UTF-8 строк
$result = preg_match('/^.$/', 'ю');
if ($result === false) {
    echo "Ошибка: " . preg_last_error();
}
Ошибка: 4

В PHP 7.3 добавлена константа PREG_JIT_STACKLIMIT_ERROR. В PHP 8.0 введена функция preg_last_error_msg(), которая дополняет preg_last_error(). Поведение самой функции preg_last_error() осталось неизменным.

Начиная с PHP 8.0, многие ошибки PCRE теперь генерируют исключения типа ValueError или Error, но preg_last_error() по-прежнему работает для совместимости.

Мониторинг ошибок в цикле
Пример php
<?php
$patterns = ['/valid/', '/[invalid/', '/\d+/'];
foreach ($patterns as $pattern) {
    $result = @preg_match($pattern, 'test');
    if ($result === false) {
        echo "Шаблон '{$pattern}' вызвал ошибку: " . preg_last_error_msg() . "\n";
    }
}
Шаблон '/[invalid/' вызвал ошибку: Backtrack limit exhausted
Комбинация с пользовательским обработчиком ошибок
Пример php
<?php
function safe_preg_match($pattern, $subject) {
    $result = preg_match($pattern, $subject);
    if ($result === false) {
        throw new RuntimeException(
            "PCRE error: " . preg_last_error_msg()
        );
    }
    return $result;
}

try {
    safe_preg_match('/[a-z', 'test');
} catch (RuntimeException $e) {
    echo $e->getMessage();
}
PCRE error: Backtrack limit exhausted
Отладка сложных регулярных выражений
Пример php
<?php
$html = '<div>content</div>';
$pattern = '/<(\w+)>.*<\/\1>/s';
ini_set('pcre.backtrack_limit', 1);
$result = preg_match($pattern, $html);

if ($result === false && preg_last_error() === PREG_BACKTRACK_LIMIT_ERROR) {
    echo "Требуется увеличение pcre.backtrack_limit\n";
}
Требуется увеличение pcre.backtrack_limit
Проверка корректности шаблона перед использованием
Пример php
<?php
function is_pattern_valid($pattern) {
    return @p_match($pattern, '') !== false || preg_last_error() === PREG_NO_ERROR;
}

$testPatterns = ['/^[a-z]$/', '/[a-z/', '/(?<group>\w+)/'];
foreach ($testPatterns as $p) {
    echo $p . ': ' . (is_pattern_valid($p) ? 'Valid' : 'Invalid') . "\n";
}
/^[a-z]$/: Valid
/[a-z/: Invalid
/(?<group>\w+)/: Valid

Preg last error в Python

В модуле re исключения генерируются явно. Аналогом проверки ошибок служит перехват исключений.

import re
try:
    re.compile('[')
except re.error as e:
    print(f"Ошибка регулярного выражения: {e}")
Ошибка регулярного выражения: unterminated character set at position 0

Preg last error в Javascript

В JavaScript регулярные выражения являются объектами. Ошибки обычно возникают при создании RegExp. Для проверки корректности можно использовать блок try-catch.

try {
    new RegExp('[');
} catch (e) {
    console.log(`Ошибка: ${e.message}`);
}
Ошибка: Unterminated character class

Preg last error в MySQL

В MySQL для работы с регулярными выражениями используется оператор REGEXP. Ошибки приводят к возврату NULL или 0, но детальную информацию получить сложнее.

SELECT 'text' REGEXP '[' AS result;
+--------+
| result |
+--------+
|   NULL |
+--------+

Отличие от PHP заключается в том, что в Python и JavaScript ошибки регулярных выражений приводят к исключениям, тогда как в PHP требуется явная проверка через preg_last_error().

PHP preg_last_error function comments

En
Preg last error Returns the error code of the last PCRE regex execution