PHP preg_replace 有错误。我怎样才能找出原因?

PHP preg_replace has error. How can I found out the reason?

$string = '## aaa                                                                 bbb';
$pattern = '/^(\n)?\s{0,}#{1,6}\s+| {0,}(\n)?\s{0,}#{0,} {0,}(\n)?\s{0,}$/';
$replacement = '';
echo preg_replace($pattern, $replacement, $string);

如果 "aaa" 和 "bbb" 之间的 space 大约为 50(或更少),我会得到正确的结果。但是如果我增加数字,假设 "aaa" 和 "bbb" 之间有 100 space。我得到空。我怎样才能找出原因?

该模式匹配两个选项,一个 ^(\n)?\s*#{1,6}\s+ 和另一个 *(\n)?\s*#* *(\n)?\s*$

第一个没问题,但建议将 \n 设置为可选而不是将整个组设置为可选。

第二个 *(\n)?\s*#* *(\n)?\s*$ 是一个非常低效的模式,因为有 \s* 个模式遵循一个可选的 \n 模式,而这个 \n 模式又以 * 模式。当没有 \n 时,\s* 可能会 "fall into" * 并且 leads to catastrophical backtracking 当部分模式匹配但最终子模式失败时。

所以,您可以使用

/^(\n?)\s*#{1,6}\s+| *(?:(\n)\s*)?#* *(?:(\n)\s*)?$/

regex demo

这里的重点是(?:(\n)\s*)?部分,其中\n必须的,只有在所有正则空格都匹配到[=17=后才会尝试] 然后 \s* 只有在前面有 \n 时才会尝试,因此,确保没有子模式会落入另一个。