为什么这个 preg_replace 调用返回 NULL?

XTF*_*XTF 1 php regex pcre

为什么这个调用返回NULL?正则表达式错误吗?对于test输入,它不会返回 NULL。文档说 NULL 表示错误,但它可能是什么错误?

$s = hex2bin('5b5d202073205b0d0a0d0a0d0a0d0a20202020202020203a');
// $s = 'test';
$s = preg_replace('/\[\](\s|.)*\]/s', '', $s);
var_dump($s);

// PHP 7.2.10-1+0~20181001133118.7+stretch~1.gbpb6e829 (cli) (built: Oct  1 2018 13:31:18) ( NTS )
Run Code Online (Sandbox Code Playgroud)

anu*_*ava 5

您的正则表达式导致灾难性的回溯并导致 PHP 正则表达式引擎失败。您可以使用preg_last_error()函数来检查这一点。

$r = preg_replace("/\[\](\s|.)*\]/s", "", $s);
if (preg_last_error() == PREG_BACKTRACK_LIMIT_ERROR) {
    print 'Backtrack limit was exhausted!';
}
Run Code Online (Sandbox Code Playgroud)

输出:

Backtrack limit was exhausted!
Run Code Online (Sandbox Code Playgroud)

由于此错误,您将获得NULL返回值。preg_replace根据PHP 文档preg_replace

如果找到匹配,则将返回新的主题,否则将原样返回主题,如果发生错误则返回 NULL


修复:(\s|.)使用s修饰符(DOTALL )时不需要。因为点在使用s修饰符时匹配任何字符,包括换行符。

你应该只使用这个正则表达式:

$r = preg_replace('/\[\].*?\]/s', "", $s);
echo preg_last_error();
//=> 0
Run Code Online (Sandbox Code Playgroud)