用正则表达式动态替换条件块的一部分

Dynamically replace part of a condition block with regex

有一个字符串格式:

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); 

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

我做错了什么?


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

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

所以,我可能在使用 = 符号时犯了错误,或者 space,或者 .*.

模式不匹配,因为您必须使用双转义符来匹配反斜杠 \$

除此之外,您没有匹配整行,因为这部分 ".*\"}';

之前的双引号处停止
$str = 'else if($rule==\'somerule1\')
echo \'{"s":1,"n":"name surname"}\';
else if($rule==\'somerule2\')
echo \'{"s":1,"n":"another text here"}\';';

$rule = "somerule1";
$pattern = "/else if\(\$rule=='$rule'\)\necho '{\"s\":\d+,\"n\":\"[^\"]*\"}';/";
$str = preg_replace($pattern, "", $str);
echo $str;

输出

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

Php demo

正则表达式模式可以不那么严格,更简单,也更容易 read/maintain。

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

代码:(Demo)

$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"}';

那么,我做了什么?这是 official pattern demo.

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