Как я могу проверить регулярное выражение?
Я бы хотел проверить правильность регулярного выражения в PHP, желательно до его использования. Единственный способ сделать это на самом деле пытается preg_match()
и посмотреть, вернет ли он FALSE
?
Существует ли более простой/правильный способ проверки правильного регулярного выражения?
Ответы
Ответ 1
// 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()
) в тестовой среде для предотвращения предупреждений или уведомлений.
Чтобы проверить, что RegExp запускает его только с помощью null
(вам не нужно знать данные, которые вы хотите протестировать против upfront). Если он возвращает явное ложное (=== false
), оно прерывается. В противном случае он действителен, хотя ему ничего не нужно.
Поэтому нет необходимости писать свой собственный валидатор RegExp. Впустую время...
Ответ 2
Я создал простую функцию, которую можно вызвать для проверки 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();
Альтернатива - Онлайн-тестер регулярных выражений
Ответ 3
Если вы хотите динамически протестировать регулярное выражение preg_match(...) === false
, кажется, ваш единственный вариант. PHP не имеет механизма для компиляции регулярных выражений до их использования.
Также вы можете найти preg_last_error полезную функцию.
С другой стороны, если у вас есть регулярное выражение и просто хочу знать, действительно ли он действителен перед его использованием, есть множество инструментов, доступных там. Я нашел rubular.com, чтобы быть приятным в использовании.
Ответ 4
Вы можете проверить, является ли это синтаксически правильным регулярным выражением с этим кошмаром регулярного выражения, если ваш движок поддерживает рекурсию (PHP должен).
Вы не можете, как бы алгоритмически не сказать, даст ли он желаемые результаты без его запуска.
От: Существует ли регулярное выражение для определения правильного регулярного выражения?
/^((?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*)$/
Ответ 5
Без выполнения регулярного выражения вы не можете быть уверены, что он действителен. Недавно я реализовал аналогичный 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;
}
}
Ответ 6
Вы можете проверить правильное выражение с помощью регулярного выражения и до определенного предела. Ознакомьтесь с этим ответом на переполнение стека для получения дополнительной информации.
Примечание: "рекурсивное регулярное выражение" не является регулярным выражением, и эта расширенная версия регулярного выражения не соответствует расширенным регулярным выражениям.
Лучше использовать preg_match
и сопоставлять с NULL как @Claudrian сказал
Ответ 7
Итак, для всех, кто подходит к этому вопросу, вы можете проверять регулярные выражения в 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);
}
Ответ 8
Я не уверен, поддерживает ли он PCRE, но есть расширение Chrome в https://chrome.google.com/webstore/detail/cmmblmkfaijaadfjapjddbeaoffeccib под названием RegExp Tester. Я еще не использовал его, но я не могу ручаться за него, но, возможно, он может быть полезен?
Ответ 9
Я бы склонен настраивать несколько модульных тестов для вашего регулярного выражения. Таким образом вы не только сможете убедиться, что регулярное выражение действительно действительно, но также эффективно при сопоставлении.
Я нахожу, что использование TDD - эффективный способ разработки регулярного выражения и означает, что его расширение в будущем упрощается, поскольку у вас уже есть все имеющиеся тестовые примеры.
Ответ на этот вопрос дает отличный ответ на настройку модульных тестов.
Ответ 10
Вы должны попытаться сопоставить регулярное выражение с NULL
.
В PHP> = 5.5 вы можете использовать следующее для автоматического получения встроенного сообщения об ошибке, без необходимости определять собственную функцию для его получения:
preg_match($regex, NULL);
echo array_flip(get_defined_constants(true)['pcre'])[preg_last_error()];
Ответ 11
В соответствии с ссылкой PCRE, нет такого способа проверить достоверность выражения, до, который он использовал, Но я думаю, что если кто-то использует недопустимое выражение, это ошибка дизайна в этом приложении, а не во время выполнения, поэтому вы должны быть в порядке.