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

时间:2014-11-01 09:42:51

标签: php regex preg-replace

[已解决]我需要删除匹配内容中不同位置的多线强匹配的正则表达式模式,但要在第一个开始关键字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

3 个答案:

答案 0 :(得分:2)

您可以使用此模式:

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

主要的兴趣是延迟量词的成本降低,因为它每行只发生一次而不是每个字符发生一次。另一个优点是m修饰符和^(该模式仅在行的开头测试,而不是针对每个字符进行测试)。使用\Q...\E避免转义特殊字符并使图案更具可读性。

答案 1 :(得分:1)

\/\*\s*START_KEY_ONE.*?END_KEY_ONE \*\/

试试这个。参见demo.Replace with 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);

答案 2 :(得分:1)

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

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

您必须在最后添加\n,这样您才不会在输出中显示空白行。

DEMO

<强>代码:

$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

DEMO