问题
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...\Emeans "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$rulevariable because the pattern is wrapped in double quotes. - The second occurrence of
$rulein the pattern DOES need to be interpreted as the variable so it is not escaped. - The
\Ris 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