测试PHP中的正则表达式是否有效

时间:2012-01-11 18:56:30

标签: php regex

我正在编写表单验证类,并希望在验证中包含正则表达式。因此,提供的正则表达式不保证有效。

如何(有效地)检查正则表达式是否有效?

6 个答案:

答案 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;
}

Demo

答案 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;
}