ID: 10666
User Update by: [EMAIL PROTECTED]
Old-Status: Closed
Status: Open
Bug Type: PCRE related
Description: preg_replace 'e' modifier

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!


Previous Comments:
---------------------------------------------------------------------------

[2001-05-04 13:02:59] [EMAIL PROTECTED]
$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] [EMAIL PROTECTED]
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...


---------------------------------------------------------------------------


Full Bug description available at: http://bugs.php.net/?id=10666


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to