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


Я хотел бы проверить правильность регулярного выражения в PHP, желательно до его использования. Это единственный способ сделать это на самом деле, попробовав preg_match() и посмотрев, вернется ли он FALSE?

Существует ли более простой/правильный способ проверки правильности регулярного выражения?

 62
Author: alex, 2010-12-14

10 answers

// This is valid, both opening ( and closing )
var_dump(preg_match('~Valid(Regular)Expression~', null) === false);
// This is invalid, no opening ( for the closing )
var_dump(preg_match('~InvalidRegular)Expression~', null) === false);

Как сказал пользователь pozs, также подумайте о том, чтобы поместить @ перед preg_match() (@preg_match()) в среде тестирования для предотвращения предупреждений или уведомлений.

Чтобы проверить регулярное выражение, просто запустите его против null ( нет необходимости знать данные, которые вы хотите проверить заранее). Если он возвращает явное значение false (=== false), он сломан. В противном случае он действителен, хотя он не должен ни с чем совпадать.

Так что нет необходимости писать собственное регулярное выражение валидатор. Это потерянное время...

 121
Author: CodeAngry, 2012-10-23 12:51:29

Я создал простую функцию, которую можно вызвать для проверки preg

function is_preg_error()
{
    $errors = array(
        PREG_NO_ERROR               => 'Code 0 : No errors',
        PREG_INTERNAL_ERROR         => 'Code 1 : There was an internal PCRE error',
        PREG_BACKTRACK_LIMIT_ERROR  => 'Code 2 : Backtrack limit was exhausted',
        PREG_RECURSION_LIMIT_ERROR  => 'Code 3 : Recursion limit was exhausted',
        PREG_BAD_UTF8_ERROR         => 'Code 4 : The offset didn\'t correspond to the begin of a valid UTF-8 code point',
        PREG_BAD_UTF8_OFFSET_ERROR  => 'Code 5 : Malformed UTF-8 data',
    );

    return $errors[preg_last_error()];
}

Вы можете вызвать эту функцию, используя следующий код:

preg_match('/(?:\D+|<\d+>)*[!?]/', 'foobar foobar foobar');
echo is_preg_error();

Альтернатива - Онлайн-Тестер Регулярных Выражений

 21
Author: Wahyu Kristianto, 2012-10-17 02:55:37

Если вы хотите динамически протестировать регулярное выражениеpreg_match(...) === false, похоже, это ваш единственный вариант. В PHP нет механизма компиляции регулярных выражений до их использования.

Также вы можете найти preg_last_error полезную функцию.

С другой стороны, если у вас есть регулярное выражение и вы просто хотите знать, действительно ли оно, прежде чем использовать его, существует множество доступных инструментов. Я нашел rubular.com быть приятным в использовании.

 15
Author: Alin Purcaru, 2010-12-14 15:25:53

Вы можете проверить, является ли это синтаксически правильным регулярным выражением с этим кошмаром регулярного выражения, если ваш движок поддерживает рекурсию (PHP должен).

Однако вы не можете алгоритмически определить, даст ли он желаемые результаты, не запустив его.

От: Существует ли регулярное выражение для определения допустимого регулярного выражения?

/^((?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*)$/
 6
Author: evandentremont, 2017-05-23 11:33:26

Без фактического выполнения регулярного выражения у вас нет возможности убедиться, что оно действительно. Недавно я реализовал аналогичный RegexValidator для Zend Framework. Работает просто отлично.

<?php
class Nuke_Validate_RegEx extends Zend_Validate_Abstract
{
    /**
     * Error constant
     */
    const ERROR_INVALID_REGEX = 'invalidRegex';

    /**
     * Error messages
     * @var array
     */
    protected $_messageTemplates = array(
        self::ERROR_INVALID_REGEX => "This is a regular expression PHP cannot parse.");

    /**
     * Runs the actual validation
     * @param string $pattern The regular expression we are testing
     * @return bool
     */
    public function isValid($pattern)
    {
        if (@preg_match($pattern, "Lorem ipsum") === false) {
            $this->_error(self::ERROR_INVALID_REGEX);
            return false;
        }
        return true;
    }
}
 2
Author: ChrisR, 2012-10-18 13:21:01

Вы можете проверить свое регулярное выражение с помощью регулярного выражения и до определенного предела . Проверьте этот ответ на переполнение стека для получения дополнительной информации.

Примечание: "рекурсивное регулярное выражение" не является регулярным выражением, и эта расширенная версия регулярного выражения не соответствует расширенным регулярным выражениям.

Лучшим вариантом является использование preg_match и сопоставление с НУЛЕМ, как сказал @Claudrian

 1
Author: rajukoyilandy, 2017-05-23 12:10:54

Итак, вкратце, для всех, кто подходит к этому вопросу, вы можете проверять регулярные выражения в PHP с помощью такой функции.

Preg_match() возвращает 1, если шаблон соответствует заданной теме, 0, если это не так, или FALSE, если произошла ошибка. - Руководство по PHP

/**
 * Return an error message if the regular expression is invalid
 *
 * @param string $regex string to validate
 * @return string
 */
function invalidRegex($regex)
{
    if(preg_match($regex, null) !== false)
    {
        return '';
    }

    $errors = array(
        PREG_NO_ERROR               => 'Code 0 : No errors',
        PREG_INTERNAL_ERROR         => 'Code 1 : There was an internal PCRE error',
        PREG_BACKTRACK_LIMIT_ERROR  => 'Code 2 : Backtrack limit was exhausted',
        PREG_RECURSION_LIMIT_ERROR  => 'Code 3 : Recursion limit was exhausted',
        PREG_BAD_UTF8_ERROR         => 'Code 4 : The offset didn\'t correspond to the begin of a valid UTF-8 code point',
        PREG_BAD_UTF8_OFFSET_ERROR  => 'Code 5 : Malformed UTF-8 data',
    );

    return $errors[preg_last_error()];
}

Который можно использовать следующим образом.

if($error = invalidRegex('/foo//'))
{
    die($error);
}
 1
Author: Xeoncross, 2012-10-22 19:20:53

Я не уверен, поддерживает ли он PCRE, но есть расширение Chrome по адресу https://chrome.google.com/webstore/detail/cmmblmkfaijaadfjapjddbeaoffeccib называется Тестер регулярных выражений. Я сам еще не использовал его, поэтому не могу за него поручиться, но, возможно, он может быть полезен?

 1
Author: Tash Pemhiwa, 2012-10-23 08:46:12

Я был бы склонен настроить ряд модульных тестов для вашего регулярного выражения. Таким образом, вы не только сможете убедиться, что регулярное выражение действительно корректно, но и эффективно при сопоставлении.

Я считаю, что использование TDD является эффективным способом разработки регулярного выражения и означает, что его расширение в будущем упрощается, поскольку у вас уже есть все доступные тестовые примеры.

Ответ на этот вопрос содержит отличный ответ на настройку модульных тестов.

 0
Author: Rob Forrest, 2017-05-23 12:18:34

Согласно ссылке PCRE , нет такого способа проверить правильность выражения до его использования . Но я думаю, что если кто-то использует неверное выражение, это ошибка проектирования в этом приложении, а не во время выполнения, так что с вами все будет в порядке.

 -3
Author: pozs, 2012-10-20 12:11:00