我想在PHP中测试正则表达式的有效性,最好是在使用它之前。唯一的方法是尝试一个preg_match(),看看它是否返回FALSE?
是否有更简单/正确的方法来测试有效的正则表达式?
您的意思是:stackoverflow.com/questions/172303/…?
如果它不需要在代码中,你可以转到regexr.com,粘贴到regex中,然后输入与之匹配的文本。
为什么不检查PrggMatHe()以防false?
看来我参加聚会迟到了
有些答案并不认为要验证的regex可能来自应用程序的管理员用户的输入…也许应用程序有一个"联系人类型"表和一个"regex"字段…
// 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),则它将被破坏。否则它是有效的,尽管它不需要匹配任何东西。
所以不需要编写自己的regexp验证器。浪费时间…
猜猜看:操作人员说:"我想在PHP中测试正则表达式的有效性,最好是在使用它之前。"
@Cyborgx37那又怎样?我给了他一个无效的解决方案。你不需要现在你要用来对付的绳子。你只需要知道模式,看看它是否正确。如果匹配与否…这是一个不同的故事,取决于你的目标字符串。我说错了什么?
我没有投你反对票…猜猜为什么会有人。我认为你的答案很好。
注意,在一个无效的ReXEP的情况下,您的代码将显示一个警告,这对于测试表达式来说太糟糕了——您应该用EDCOX1(3)来保护您的EDOCX1 2调用。
错误抑制操作符不是一个好的解决方案,因为单元测试框架的问题和其他禁用"@"操作符进行测试。作为解决方案,您可以在测试之前使用"StestyError处理程序"和"RealthyError处理程序";
@我也不用它。但这对初学者有好处。有传言说还有一个很小的性能惩罚。但是初学者会被错误吓坏,所以最好提出来,直到他们学会正确地抑制/记录/处理错误为止。
也许值得一提的是,由于null也被转换为空字符串(preg_match('~.?~', null) === 1),所以可以使用$subject中的任何字符串作为preg_match()的一种方法来测试正则表达式,而不是在使用之前测试它的方法(w/或w/o真实数据)。
我创建了一个简单的函数,可以调用它来检查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+|)*[!?]/', 'foobar foobar foobar');
echo is_preg_error();
替代-正则表达式在线测试仪
雷格西尔
PHP正则表达式测试仪
正则表达式工具
这只是针对英语的preg_last_error的包装。
顺便说一下,这并不能真正告诉您regex是否有效。考虑:php>preg_match("/aaa",";php>echo preg_last_error();0
php 7增加了PREG_JIT_STACKLIMIT_ERROR。看文档。
如果您想动态测试一个regex preg_match(...) === false,似乎是您唯一的选择。PHP没有在使用正则表达式之前编译它们的机制。
另外,您可能会发现preg_last_错误是一个有用的函数。
另一方面,如果您有一个regex,只是想知道它在使用之前是否有效,那么有很多可用的工具。我觉得rubular.com很好用。
如果您的引擎支持递归(php应该),那么您可以通过这个regex的噩梦检查它是否是语法正确的regex。
但是,从算法上讲,如果不运行它,就无法判断它是否会给出您想要的结果。
发件人:是否有用于检测有效正则表达式的正则表达式?
/^((?:(?:[^?+*{}()[\]\\|]+|\\.|\[(?:\^?\\.|\^[^\\]|[^\\^])(?:[^\]\\]+|\\.)*\]|\((?:\?[:=!]|\?)?(?1)??\)|\(\?(?:R|[+-]?\d+)\))(?:(?:[?+*]|\{\d+(?:,\d*)?\})[?+]?)?|\|)*)$/
天哪,你在用regex验证regex?多教我一点,上帝!
这在一般情况下肯定行不通?
这个regex是递归的。所以,在这个词的经典意义上,它不是regex,但它在与Perl兼容的正则表达式引擎中工作。
如果不执行regex,就无法确定它是否有效。我最近为Zend框架实现了类似的regexvalidator。工作很好。
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;
}
}
我不确定它是否支持PCRE,但是在https://chrome.google.com/webstore/detail/cmmblmkfaijaadfjapjdbeaoffeccib有一个chrome扩展名为regexp tester。我还没有自己用过它,所以我不能担保它,但也许它是有用的?
总之,对于所有涉及到这个问题的人,您可以用这样的函数验证PHP中的正则表达式。
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred. - PHP Manual
/**
* 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);
}
您可以使用正则表达式来验证正则表达式,并达到一定的限制。有关详细信息,请签出此堆栈溢出应答。
注意:"递归正则表达式"不是正则表达式,而且此扩展版本的regex与扩展的regex不匹配。
一个更好的选择是使用preg_match并与空匹配,正如@claudrian所说。
您应该尝试将正则表达式与null匹配。如果结果是错误的(=== false),则出现错误。
在php>=5.5中,您可以使用以下命令自动获取内置错误消息,而无需定义自己的函数即可获取:
我倾向于为您的regex设置一些单元测试。这样不仅可以确保regex确实有效,而且在匹配时也有效。
我发现使用TDD是开发regex的有效方法,这意味着在将来扩展regex会简化,因为您已经拥有了所有可用的测试用例。
这个问题的答案对于设置单元测试有很好的答案。
谢谢Rob。我是TDD的粉丝,但是所讨论的代码需要能够将regex作为输入进行验证(我正在验证JSON模式,它可以包含regex模式)。
根据PCRE参考,在使用表达式之前,没有这样的方法来测试它的有效性。但我认为,如果有人使用了一个无效的表达式,那是该应用程序中的设计错误,而不是运行时错误,所以您应该很好。
-1因为OP的问题不是在它被使用之前,而是在它被用于实际数据之前。一件事是用5MB的数据进行测试,另一件事是用一个空字符串来验证regexp是否编译。所以,在PHP中你可以测试它,在C++中你可以测试它。在C++ 11中,如果无效,则在PHP中得到显式false。任何regexp都是在执行之前编译的,当它是非法的时,错误就会出现在编译失败的地方,不管您将对其使用什么数据。谢斯…
@克劳德里安:我同意,但这个问题不是在它被用于实际数据之前,而是在它被使用之前——而且没有这样的方法(作为一个明确的/专门的函数)。但是我同意,如果你真的想测试它,就应该对空值进行测试。