Bug #10666 Updated: preg_replace 'e' modifier
| From: | smoonen at andstuff dot org | Date: | Fri, 03 Aug 2001 16:01:46 +0000 |
| Subject: | Bug #10666 Updated: preg_replace 'e' modifier | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-61981@lists.php.net to get a copy of this message | ||
ID: 10666
User updated by: smoonen@andstuff.org
Reported By: smoonen@andstuff.org
Old Status: Open
Status: Closed
Bug Type: PCRE related
Operating System: Linux
PHP Version: 4.0.5
New Comment:
Strangely, while the bug referenced in my update at [2001-05-04 13:55:39] was very repeatable across
several PHP installations, I can no longer duplicate it.
Am closing the bug, though in my dreams I still wish for $n pseudovariables. ;-)
Previous Comments:
------------------------------------------------------------------------
[2001-05-04 14:36:12] smoonen@andstuff.org
Also, as a merely informational aside, PHP's use of $1 is in this instance actually
incompatible with Perl. Perl, in a s///e expression, treats $n as a variable rather than expanding
it in-place.
Hence my preference. :-)
------------------------------------------------------------------------
[2001-05-04 13:55:39] smoonen@andstuff.org
Okay. Then I have a problem with how backslash escaping is inconsistently applied when using \\1
and $1.
Specifically, consider the following:
function f($x) { print $x; }
$s = "a' \\ \"b";
$s = preg_replace('/a(.*)b/e', 'f("$1")', $s, -1);
The single quote is escaped; I'd rather it weren't but that's okay. But the
backslash itself isn't escaped! This prevents me from running stripslashes() on the match,
since I can't guarantee that every backslash has been properly escaped.
Worse, the following will actually fail:
function f($x) { print $x; }
$s = "a' \" \\b";
$s = preg_replace('/a(.*)b/e', 'f("$1")', $s, -1);
Since the final backslash hasn't been escaped, it actually slurps up the second double-quote in
'f("$1")'!
I'd like to see either of the following:
1. $1 treated as a "real" variable, rather than a string
substitution. This is convenient, since it saves me
having to call stripslashes().
2. Backslash escapes consistently applied in backrefs.
Specifically, escape existing backslashes in the match.
Presently, I can't perform a stripslashes() -- and in
some cases, as indicated above, it fails altogether!
------------------------------------------------------------------------
[2001-05-04 13:02:59] andrei@php.net
$n notation was introduced to be similar to Perl. It is exactly equivalent to \\n.
You can't simply use f($1) in the evaluation string because $1 is replaced with the matched
contents and after replacement it becomes, in your example, f(abc def), which is not valid PHP code.
So you have to use f("$1") or f('$1').
The fact that it backslash-escapes single and double quotes in matches before substituting $1 is a
feature, not a bug, otherwise you'd have a really hard time figuring out which quotes go where
when using evaluation strings.
------------------------------------------------------------------------
[2001-05-04 11:27:54] smoonen@andstuff.org
Formerly, preg_replace's "e" modifier inserted extraneous backslashes in
backreferences of "\\1" or '\\1' form.
Ostensibly, the $1 backreference form was added to fix this. However, the following code fails:
function f($x) { return 'yo'; }
$s = "xyzabc def123";
$s = preg_replace('/(abc def)/e', 'f($1)', $s, -1);
It seems to be trying to evaluate $1 as code, rather than as a variable containing the contents
"abc def".
This is borne out by the fact that the following succeeds:
$s = preg_replace('/(abc def)/e', 'f("$1")', $s, -1);
But "$1" and '$1' are no better than "\\1" and '\\1', since
it still inserts extraneous backslashes before single quotes or double quotes (respectively)!!!
I was sincerely hoping that PHP 4.04 and 4.05 would fix this oversight, since my web application
depends on it. I'm keeping my fingers crossed that it's just me doing something wrong,
though I doubt it...
------------------------------------------------------------------------
Edit this bug report at http://bugs.php.net/?id=10666&edit=1