$string = '## aaa bbb';
$pattern = '/^(n)?s{0,}#{1,6}s+| {0,}(n)?s{0,}#{0,} {0,}(n)?s{0,}$/';
$replacement = '$1$2$3';
echo preg_replace($pattern, $replacement, $string);
如果"aaa"和"bbb"之间的空间在 50(或更小(左右,我确实得到了正确的结果。 但是如果我增加数字,假设"aaa"和"bbb"之间有 100 个空格。 我得到空。 我怎样才能找出原因?
该模式匹配两个备选方案,一个^(n)?s*#{1,6}s+
,另一个*(n)?s*#* *(n)?s*$
。
第一个是可以的,但建议将n
设置为可选,而不是使整个组可选。
第二个,*(n)?s*#* *(n)?s*$
,是一种非常低效的模式,因为有s*
模式遵循可选的n
模式,而该模式又在*
模式之前。当没有n
时,s*
可能会"陷入"*
,当部分形态匹配但最终子形态失败时,这会导致灾难性的回溯。
因此,您可以使用
/^(n?)s*#{1,6}s+| *(?:(n)s*)?#* *(?:(n)s*)?$/
查看正则表达式演示
这里的关键点是(?:(n)s*)?
n
是强制性的,只有在所有常规空间与*
匹配后才会尝试s*
然后只有在之前有n
时才尝试,从而确保没有子模式会落入另一个。