用正则表达式动态替换条件块的一部分
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"}';
正则表达式模式可以不那么严格,更简单,也更容易 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.
\Q
...\E
表示“从字面上处理这两个元字符之间的所有内容”
- 然后唯一需要转义的字符是第一个
$
,这并不是要阻止它被解释为字符串结束元字符,而是作为 $rule
的开始变量 因为 模式用双引号引起来。
- 模式中第二次出现的
$rule
确实需要被解释为变量,因此它不会被转义。
\R
是一个元字符,意思是\n, \r and \r\n
- 最后用一个或多个量词 (
+
). 匹配“任何字符”.
的所有下一行
有一个字符串格式:
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"}';
正则表达式模式可以不那么严格,更简单,也更容易 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.
\Q
...\E
表示“从字面上处理这两个元字符之间的所有内容”- 然后唯一需要转义的字符是第一个
$
,这并不是要阻止它被解释为字符串结束元字符,而是作为$rule
的开始变量 因为 模式用双引号引起来。 - 模式中第二次出现的
$rule
确实需要被解释为变量,因此它不会被转义。 \R
是一个元字符,意思是\n, \r and \r\n- 最后用一个或多个量词 (
+
). 匹配“任何字符”
.
的所有下一行