Dynamically replace part of a condition block with regex

有些话、适合烂在心里 提交于 2020-12-12 10:50:10

问题


There is a string in format:

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

"s" can have only number, "n" any text.

In input I have $rule value, and I need to remove the else if block that corresponds to this value. I am trying this:

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

where $str is a string, that contains blocks I mentioned above, $rule is a string with rule I need to remove. But the function returns $str without changes.

What do I do wrong?


For example, script to change "s" value to 1 works nice:

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

So, probably, I am doing mistake with = symbol, or maybe with space, or with .*.


回答1:


The regex pattern can be much less strict, much simpler, and far easier to read/maintain.

You need to literally match the first line (conditional expression) with the only dynamic component being the $rule variable, then match the entire line that immediately follows it.

Code: (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);

Output:

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

So, what have I done? Here's the official pattern demo.

  1. \Q...\E means "treat everything in between these two metacharacters literally"
  2. Then the only character that needs escaping is the first $, this is not to stop it from being interpreted as a end-of-string metacharacter, but as the start of the $rule variable because the pattern is wrapped in double quotes.
  3. The second occurrence of $rule in the pattern DOES need to be interpreted as the variable so it is not escaped.
  4. The \R is a metacharacter which means \n, \r and \r\n
  5. Finally match all of the next line with the "any character" . with a one or more quantifier (+).



回答2:


The pattern does not match because you have to use a double escape to match the backslash \\\$.

Apart from that, you are not matching the whole line as this part ".*\" stops at the double quote before }';

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

Output

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

Php demo



来源:https://stackoverflow.com/questions/64818623/dynamically-replace-part-of-a-condition-block-with-regex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!