ID:               10666
 Comment by:       info at webprog dot de
 Reported By:      smoonen at andstuff dot org
 Status:           Closed
 Bug Type:         PCRE related
 Operating System: Linux
 PHP Version:      4.0.5
 New Comment:

3 Years ago its allready a feature? :-)
I build something like this:

$r = "<span lang=\"en\" xml:lang=\"en\">".$words."</span>";

$this->template = preg_replace ("/((<[^>]*)|(^|
|>)($words)([^a-zA-Z]|$))/e", '"\\2"=="\\1"? "\\1":"\\3<span
lang=\"en\" xml:lang=\"en\">\\4</span>\\5"', $this->template);

...and it works fine with Perl and bad with PHP, because it sets in
front of every single quote a backslash.


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

[2001-08-03 12:01:46] smoonen at andstuff dot org

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. ;-)

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

[2001-05-04 14:36:12] smoonen at andstuff dot 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 at andstuff dot 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] [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] smoonen at andstuff dot 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

Reply via email to