Проверьте, является ли регулярное выражение допустимым в PHP

Я пишу класс проверки формы и хочу включить регулярные выражения в проверку. Следовательно, регулярное выражение не гарантируется.

Как я могу (эффективно) проверить правильность регулярного выражения?

Ответ 1

Используйте шаблон в ваших вызовах preg_*. Если функция возвращает false, вероятно, проблема с вашим шаблоном. Насколько я знаю, это самый простой способ проверить правильность шаблона регулярного выражения в PHP.


Здесь пример, указывающий правильный вид булевой проверки:

$invalidPattern = 'i am not valid regex';
$subject = 'This is some text I am searching in';
if (@preg_match($invalidPattern, $subject) === false) {
    // the regex failed and is likely invalid
}

Ответ 2

Вы не должны использовать @, чтобы заглушить все ошибки, потому что он также замалчивает фатальные ошибки.

function isRegularExpression($string) {
  set_error_handler(function() {}, E_WARNING);
  $isRegularExpression = preg_match($string, "") !== FALSE;
  restore_error_handler();
  return isRegularExpression;
}

Это только отключает предупреждения для вызова preg_match.

Ответ 3

Когда вы сообщаете об ошибках, вы не можете уйти, просто протестировав логический результат. Если ошибка регулярного выражения не срабатывает, предупреждения бросаются (т.е. "Предупреждение: окончательный разделитель xxx не найден".)

То, что я нахожу странным, заключается в том, что документация PHP ничего не сообщает об этих брошенных предупреждениях.

Ниже мое решение для этой проблемы, используя try, catch.

//Enable all errors to be reported. E_WARNING is what we must catch, but I like to have all errors reported, always.
error_reporting(E_ALL);
ini_set('display_errors', 1);

//My error handler for handling exceptions.
set_error_handler(function($severity, $message, $file, $line)
{
    if(!(error_reporting() & $severity))
    {
        return;
    }
    throw new ErrorException($message, $severity, $severity, $file, $line);
});

//Very long function name for example purpose.
function checkRegexOkWithoutNoticesOrExceptions($test)
{
    try
    {
        preg_match($test, '');
        return true;
    }
    catch(Exception $e)
    {
        return false;
    }
}

Ответ 4

Любой, кто все еще рассматривает этот вопрос anno 2018 и использует php 7, должен использовать try/catch.

try { 
    preg_match($mypattern, '');
} catch (\Throwable $exception) {
    // regex was invalid and more info is in $exception->getMessage()
}

Ответ 5

Это мое решение с использованием предстоящего предупреждения, если что-то не так с выражением:

function isRegEx($test)
{
    $notThisLine = error_get_last();
    $notThisLine = isset($notThisLine['line']) ? $notThisLine['line'] + 0 : 0;
    while (($lines = rand(1, 100)) == $notThisLine);
    eval(
        str_repeat("\n", $lines) . 
        '@preg_match(\'' . addslashes($test) . '\', \'\');'
    );
    $check = error_get_last();
    $check = isset($check['line']) ? $check['line'] + 0 : 0;
    return $check == $notThisLine;
}