Как я могу проверить регулярное выражение?
Я хотел бы проверить правильность регулярного выражения в PHP, желательно до его использования. Это единственный способ сделать это на самом деле, попробовав preg_match()
и посмотрев, вернется ли он FALSE
?
Существует ли более простой/правильный способ проверки правильности регулярного выражения?
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
), он сломан. В противном случае он действителен, хотя он не должен ни с чем совпадать.
Так что нет необходимости писать собственное регулярное выражение валидатор. Это потерянное время...
Я создал простую функцию, которую можно вызвать для проверки 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();
Альтернатива - Онлайн-Тестер Регулярных Выражений
Если вы хотите динамически протестировать регулярное выражениеpreg_match(...) === false
, похоже, это ваш единственный вариант. В PHP нет механизма компиляции регулярных выражений до их использования.
Также вы можете найти preg_last_error полезную функцию.
С другой стороны, если у вас есть регулярное выражение и вы просто хотите знать, действительно ли оно, прежде чем использовать его, существует множество доступных инструментов. Я нашел rubular.com быть приятным в использовании.
Вы можете проверить, является ли это синтаксически правильным регулярным выражением с этим кошмаром регулярного выражения, если ваш движок поддерживает рекурсию (PHP должен).
Однако вы не можете алгоритмически определить, даст ли он желаемые результаты, не запустив его.
От: Существует ли регулярное выражение для определения допустимого регулярного выражения?
/^((?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*)$/
Без фактического выполнения регулярного выражения у вас нет возможности убедиться, что оно действительно. Недавно я реализовал аналогичный 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;
}
}
Вы можете проверить свое регулярное выражение с помощью регулярного выражения и до определенного предела . Проверьте этот ответ на переполнение стека для получения дополнительной информации.
Примечание: "рекурсивное регулярное выражение" не является регулярным выражением, и эта расширенная версия регулярного выражения не соответствует расширенным регулярным выражениям.
Лучшим вариантом является использование preg_match
и сопоставление с НУЛЕМ, как сказал @Claudrian
Итак, вкратце, для всех, кто подходит к этому вопросу, вы можете проверять регулярные выражения в 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);
}
Я не уверен, поддерживает ли он PCRE, но есть расширение Chrome по адресу https://chrome.google.com/webstore/detail/cmmblmkfaijaadfjapjddbeaoffeccib называется Тестер регулярных выражений. Я сам еще не использовал его, поэтому не могу за него поручиться, но, возможно, он может быть полезен?
Я был бы склонен настроить ряд модульных тестов для вашего регулярного выражения. Таким образом, вы не только сможете убедиться, что регулярное выражение действительно корректно, но и эффективно при сопоставлении.
Я считаю, что использование TDD является эффективным способом разработки регулярного выражения и означает, что его расширение в будущем упрощается, поскольку у вас уже есть все доступные тестовые примеры.
Ответ на этот вопрос содержит отличный ответ на настройку модульных тестов.
Согласно ссылке PCRE , нет такого способа проверить правильность выражения до его использования . Но я думаю, что если кто-то использует неверное выражение, это ошибка проектирования в этом приложении, а не во время выполнения, так что с вами все будет в порядке.