首页 > 解决方案 > 用正则表达式动态替换条件块的一部分

问题描述

格式中有一个字符串:

else if($rule=='somerule1')
echo '{"s":1,"n":"name surname"}';
else if($rule=='somerule2')
echo '{"s":1,"n":"another text here"}';
...

"s"只能有数字,"n"任何文本。

在输入中我有$rule值,我需要删除与else if该值对应的块。我正在尝试这个:

$str = preg_replace("/else if\(\$rule=='$rule'\)\necho '{\"s\":[0-9],\"n\":\".*\"/", "", $str); 

where$str是一个包含我上面提到的块的字符串,$rule是一个带有我需要删除的规则的字符串。但是函数返回$str没有变化。

我做错了什么?


例如,将"s"值更改为 1 的脚本效果很好:

$str = preg_replace("/$rule'\)\necho '{\"s\":[0-9]/", $rule."')\necho '{\"s\":1", $str);

所以,很可能,我在=符号、空间或.*.

标签: phpregexpreg-replace

解决方案


正则表达式模式可以不那么严格,简单得多,并且更容易阅读/维护。

您需要将第一行(条件表达式)与唯一的动态组件进行逐字匹配$rule,然后匹配紧随其后的整行。

代码:(演示

$contents = <<<'TEXT'
else if($rule=='somerule1')
echo '{"s":1,"n":"name surname"}';
else if($rule=='somerule2')
echo '{"s":1,"n":"another text here"}';
TEXT;

$rule = "somerule1";

echo preg_replace("~\Qelse if(\$rule=='$rule')\E\R.+~", "", $contents);

输出:

else if($rule=='somerule2')
echo '{"s":1,"n":"another text here"}';

那么,我做了什么?这是官方模式演示

  1. \Q...\E表示“从字面上处理这两个元字符之间的所有内容”
  2. 那么唯一需要转义的字符是第一个$,这并不是要阻止它被解释为字符串结尾的元字符,而是作为$rule变量的开头,因为模式用双引号括起来。
  3. 模式中第二次出现的$rule确实需要被解释为变量,因此它不会被转义。
  4. \R一个元字符,表示\n、\r 和 \r\n
  5. .最后用一个或多个量词 ( )匹配所有下一行与“任何字符” +

推荐阅读