note 39713 deleted from function.preg-replace by crell

From: Date: Fri, 01 Jul 2022 19:47:47 +0000
Subject: note 39713 deleted from function.preg-replace by crell
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-218857@lists.php.net to get a copy of this message
Note Submitter: steven -a-t- acko dot net ---- People using the /e modifier with preg_replace should be aware of the following weird behaviour. It is not a bug per se, but can cause bugs if you don't know it's there. The example in the docs for /e suffers from this mistake in fact. With /e, the replacement string is a PHP expression. So when you use a backreference in the replacement expression, you need to put the backreference inside quotes, or otherwise it would be interpreted as PHP code. Like the example from the manual for preg_replace: preg_replace("/(<\/?)(\w+)([^>]*>)/e", "'\\1'.strtoupper('\\2').'\\3'", $html_body); To make this easier, the data in a backreference with /e is run through addslashes() before being inserted in your replacement expression. So if you have the string He said: "You're here" It would become: He said: \"You\'re here\" ...and be inserted into the expression. However, if you put this inside a set of single quotes, PHP will not strip away all the slashes correctly! Try this: print ' He said: \"You\'re here\" '; Output: He said: \"You're here\" This is because the sequence \" inside single quotes is not recognized as anything special, and it is output literally. Using double-quotes to surround the string/backreference will not help either, because inside double-quotes, the sequence \' is not recognized and also output literally. And in fact, if you have any dollar signs in your data, they would be interpreted as PHP variables. So double-quotes are not an option. The 'solution' is to manually fix it in your expression. It is easiest to use a separate processing function, and do the replacing there (i.e. use "my_processing_function('\\1')" or something similar as replacement expression, and do the fixing in that function). If you surrounded your backreference by single-quotes, the double-quotes are corrupt: $text = str_replace('\"', '"', $text); People using preg_replace with /e should at least be aware of this. I'm not sure how it would be best fixed in preg_replace. Because double-quotes are a really bad idea anyway (due to the variable expansion), I would suggest that preg_replace's auto-escaping is modified to suit the placement of backreferences inside single-quotes (which seemed to be the intention from the start, but was incorrectly applied).

« previous php.notes (#218857) next »