问题
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.
\Q
...\E
means "treat everything in between these two metacharacters literally"- 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. - The second occurrence of
$rule
in the pattern DOES need to be interpreted as the variable so it is not escaped. - The
\R
is a metacharacter which means \n, \r and \r\n - 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