我正在编写表单验证类,并希望在验证中包含正则表达式。因此,提供的正则表达式不保证有效。
如何(有效地)检查正则表达式是否有效?
答案 0 :(得分:19)
使用preg_*
来电中的模式。如果函数返回false
,则模式可能存在问题。据我所知,这是检查正则表达式模式在PHP中是否有效的最简单方法。
这是一个指定正确类型的布尔检查的示例:
$invalidPattern = 'i am not valid regex';
$subject = 'This is some text I am searching in';
if (@preg_match($invalidPattern, $subject) === false) {
// the regex failed and is likely invalid
}
答案 1 :(得分:2)
你不应该使用@来消除所有错误,因为它也会使致命错误消失。
function isRegularExpression($string) {
set_error_handler(function() {}, E_WARNING);
$isRegularExpression = preg_match($string, "") !== FALSE;
restore_error_handler();
return isRegularExpression;
}
这只会使preg_match调用的警告无效。
答案 2 :(得分:1)
当您有错误报告时,您无法轻松测试布尔结果。如果正则表达式失败则抛出警告(即'警告:未找到结束分隔符xxx'。)
我觉得奇怪的是,PHP文档没有说明这些抛出的警告。
以下是我使用try,catch。解决此问题的方法。
//Enable all errors to be reported. E_WARNING is what we must catch, but I like to have all errors reported, always.
error_reporting(E_ALL);
ini_set('display_errors', 1);
//My error handler for handling exceptions.
set_error_handler(function($severity, $message, $file, $line)
{
if(!(error_reporting() & $severity))
{
return;
}
throw new ErrorException($message, $severity, $severity, $file, $line);
});
//Very long function name for example purpose.
function checkRegexOkWithoutNoticesOrExceptions($test)
{
try
{
preg_match($test, '');
return true;
}
catch(Exception $e)
{
return false;
}
}
答案 3 :(得分:1)
自从首次提出(并回答)这个问题以来,PHP取得了长足的进步。现在,您可以使用PHP 5.2+编写以下代码,不仅测试正则表达式是否有效,而且还可以获取详细的错误消息:
if(@preg_match($pattern, '') === false){
echo error_get_last()["message"];
}
放置在函数中
/**
* Return an error message if the given pattern argument or its underlying regular expression
* are not syntactically valid. Otherwise (if they are valid), NULL is returned.
*
* @param $pattern
*
* @return string|null
*/
function regexHasErrors($pattern): ?string
{
if(@preg_match($pattern, '') === false){
//Silence the error by using a @
return str_replace("preg_match(): ", "", error_get_last()["message"]);
//Make it prettier by removing the function name prefix
}
return NULL;
}
答案 4 :(得分:0)
任何人仍在2018年春季之前看到这个问题,并且正在使用php 7,应该使用try / catch。
try {
preg_match($mypattern, '');
} catch (\Throwable $exception) {
// regex was invalid and more info is in $exception->getMessage()
}
答案 5 :(得分:-7)
如果表达式出现问题,这是我使用即将发出警告的解决方案:
function isRegEx($test)
{
$notThisLine = error_get_last();
$notThisLine = isset($notThisLine['line']) ? $notThisLine['line'] + 0 : 0;
while (($lines = rand(1, 100)) == $notThisLine);
eval(
str_repeat("\n", $lines) .
'@preg_match(\'' . addslashes($test) . '\', \'\');'
);
$check = error_get_last();
$check = isset($check['line']) ? $check['line'] + 0 : 0;
return $check == $notThisLine;
}