Preg last error: примеры (PHP)
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
<?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
$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
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
$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
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().