PHP删除多次出现的带有排除的多行模式


PHP Remove multiple occurrences of multiline pattern with exclusion

[SOLVED]我需要实现删除与内容中不同位置的多行强分布匹配的regexp模式,但要排除第一个开始关键字start_KEY_ONE和最后一个结束关键字END_KEY_ONE之间的部分。

一般来说,以下是代码示例:

$content = <<<EOS
Line 1
Line 2
/* START_KEY_ONE */
Line 3
Line 4
Line 5
/* END_KEY_ONE */
Line 6
Line 7
/* START_KEY_TWO */
Line 8
/* END_KEY_TWO */
Line 9
Line 10
/* START_KEY_ONE */
Line 11
Line 12
/* END_KEY_ONE */
Line 13
/* START_KEY_TWO */
Line 14
/* END_KEY_TWO */
Line 15
EOS;
// $needle = '#/'* START_KEY_ONE.*END_KEY_ONE '*/'R#s'; // non working pattern
$needle = '#/'* START_KEY_ONE.*?END_KEY_ONE '*/'R#s'; // working pattern
echo preg_replace($needle,'',$content);

代替这个(工作模式):

Line 1
Line 2
Line 6
Line 7
/* START_KEY_TWO */
Line 8
/* END_KEY_TWO */
Line 9
Line 10
Line 13
/* START_KEY_TWO */
Line 14
/* END_KEY_TWO */
Line 15

我得到了这个(非工作模式):

Line 1
Line 2
Line 13
/* START_KEY_TWO */
Line 14
/* END_KEY_TWO */
Line 15

您可以使用以下模式:

~^'Q/* START_KEY_ONE */'E'R(?>.*'R)*?'Q/* END_KEY_ONE */'E'R?~m

主要的兴趣是懒惰量词的成本降低了,因为它每行只出现一次,而不是每字符出现一次。另一个优点是m修饰符和^锚点(模式只在一行的开头测试,而不是针对每个字符)'Q...'E的使用避免了转义特殊字符,使模式更具可读性。

'/'*'s*START_KEY_ONE.*?END_KEY_ONE '*'/

试试这个。请参阅演示。更换为empty string

请参阅演示。

http://regex101.com/r/jI8lV7/4

$re = "/''/''*''s*START_KEY_ONE.*?END_KEY_ONE ''*''//s";
$str = "Line 1'nLine 2'n/* START_KEY_ONE */'nLine 3'nLine 4'nLine 5'n/* END_KEY_ONE */'nLine 6'nLine 7'n/* START_KEY_TWO */'nLine 8'n/* END_KEY_TWO */'nLine 9'nLine 10'n/* START_KEY_ONE */'nLine 11'nLine 12'n/* END_KEY_ONE */'nLine 13'n/* START_KEY_TWO */'nLine 14'n/* END_KEY_TWO */'nLine 15";
$subst = "";
$result = preg_replace($re, $subst, $str);

如下更改正则表达式,然后用空字符串替换匹配项。不要忘记在正则表达式中添加s DOTALL修饰符。

'~/'*'h+START_KEY_ONE'h+'*/.*?END_KEY_ONE'h+'*/'n~s'

最后必须添加'n,这样输出中就不会出现空行。

演示

代码:

$content = <<<EOS
Line 1
Line 2
/* START_KEY_ONE */
Line 3
Line 4
Line 5
/* END_KEY_ONE */
Line 6
Line 7
/* START_KEY_TWO */
Line 8
/* END_KEY_TWO */
Line 9
Line 10
/* START_KEY_ONE */
Line 11
Line 12
/* END_KEY_ONE */
Line 13
/* START_KEY_TWO */
Line 14
/* END_KEY_TWO */
Line 15
EOS;
$needle = '~/'*'h+START_KEY_ONE'h+'*/.*?END_KEY_ONE'h+'*/'n~s';
echo preg_replace($needle,'',$content);

输出:

Line 1
Line 2
Line 6
Line 7
/* START_KEY_TWO */
Line 8
/* END_KEY_TWO */
Line 9
Line 10
Line 13
/* START_KEY_TWO */
Line 14
/* END_KEY_TWO */
Line 15

演示