我想在PHP中测试正则表达式的有效性,最好在使用前进行测试。这样做的唯一方法是实际尝试apreg_match()
并查看其是否返回FALSE
吗?
有没有更简单/正确的方法来测试有效的正则表达式?
我想在PHP中测试正则表达式的有效性,最好在使用前进行测试。这样做的唯一方法是实际尝试apreg_match()
并查看其是否返回FALSE
吗?
有没有更简单/正确的方法来测试有效的正则表达式?
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()()前面,以防止发出警告或通知。
要验证RegExp只需对其运行null
(无需知道您要预先测试的数据)。如果返回显式false(=== false
),则表示它已损坏。否则它是有效的,尽管它不需要匹配任何内容。
因此,无需编写自己的RegExp验证器。 浪费时间了...
preg_match()
使用@
我创建了一个简单的函数,可以调用它检查预浸料
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_last_error
针对英语的包装。
PREG_JIT_STACKLIMIT_ERROR
。请参阅文档。
如果要动态测试正则表达式preg_match(...) === false
似乎是您唯一的选择。PHP没有使用正则表达式之前对其进行编译的机制。
另外,您可能会发现preg_last_error是有用的功能。
另一方面,如果您有一个正则表达式,并且只想在使用前知道它是否有效,则可以使用大量工具。我发现rubular.com使用起来很愉快。
如果您的引擎支持递归(PHP应该),则可以检查此正则表达式的噩梦,看看它是否在语法上正确。
但是,您无法在不运行算法的情况下从算法上确定它是否可以提供所需的结果。
/^((?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?<[=!]|\?>)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*)$/
没有实际执行正则表达式,您将无法确定它是否有效。我最近为Zend Framework实现了一个类似的RegexValidator。效果很好。
<?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;
}
}
因此,总而言之,对于所有遇到此问题的人,您都可以使用这样的函数来验证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,但https://chrome.google.com/webstore/detail/cmmblmkfaijaadfjapjddbeaoffeccib上有一个Chrome扩展程序,称为RegExp Tester。我本人还没有使用过它,所以我不能担保它,但是也许它有用吗?
根据PCRE参考,在使用表达式之前,尚无方法测试表达式的有效性。但是我认为,如果有人使用无效的表达式,那是该应用程序中的一个设计错误,而不是运行时错误,因此您应该没事。