#43532 [Opn]: preg_replace: Escaping \ and $n in 2nd arg
| From: | csaba at alum dot mit dot edu | Date: | Sat, 08 Dec 2007 12:28:13 +0000 |
| Subject: | #43532 [Opn]: preg_replace: Escaping \ and $n in 2nd arg | ||
| References: | 1 | Groups: | php.doc.bugs |
| Request: | Send a blank email to doc-bugs+get-330@lists.php.net to get a copy of this message | ||
ID: 43532
User updated by: csaba at alum dot mit dot edu
Reported By: csaba at alum dot mit dot edu
Status: Open
Bug Type: Documentation problem
PHP Version: Irrelevant
New Comment:
That passage concerns (backlashes in) regular expression ->patterns<-
and does not apply here. My example does not have any backslashes in
the pattern (which is the 1st argument to preg_replace). My report only
concerns backslashes in the replacement (which is the 2nd argument).
Csaba
By the way, the section that you quoted and the paragraph above it is
gramatically incorrect ("strings have special meaning of backslash" is
improper. In addition double backslashes are treated the same in all
three types of PHP strings (single quoted, double quoted, heredoc) so
the type of PHP string should not be qualified. Also, the use of the
word "write" is ambiguous (because when one writes "\\" one gets a
single backslash), and is particularly confusing as a result. I would
reword it thusly:
For example, to match a "*" character, the pattern should contain "\*"
(backslash asterisk). This applies whether or not the following
character would otherwise be interpreted as a meta-character. It is
always safe to precede a non-alphanumeric with backslash (\) to specify
that the character itself is being matched. In particular, to match a
backslash, the pattern should contain \\ (two backslashes).
Note: A backslash escapes the following backslash within PHP
strings. Thus, if \ has to be matched by a regular expression pattern
\\, then four backslahses (\\\\) are required in the php string. E.g.
preg_match("/\\\\/", $subject) matches a single backslash in $subject.
(If only the most offending sentence is to be changed, then it should
be reworded thusly: Backslash has special meaning within PHP strings.)
Previous Comments:
------------------------------------------------------------------------
[2007-12-08 09:51:11] felipe@php.net
The documentation says:
"Note: Single and double quoted PHP strings have special meaning of
backslash. Thus if \ has to be matched with a regular expression \\,
then "\\\\" or '\\\\' must be used in PHP code."
(Maybe the escape will be changed in this post)
Its mentioned in:
http://br2.php.net/manual/en/reference.pcre.pattern.syntax.php
------------------------------------------------------------------------
[2007-12-08 02:03:51] csaba at alum dot mit dot edu
Description:
------------
preg_replace("/x/", '\\\\', "axb")
=> a\b
This has been reported at least 5 times as a bug in PHP (bugs 11594,
12668, 17616, 34560, 10626), and each time the answer comes back that
it's not a bug in PHP, and to check the documentation.
There is nothing in the documentation to indicate this behaviour,
especially with no /e modifier, so the documentation should be revised.
I would suggest something like the below - edit to suit:
Csaba Gabor from Vienna
$replacement has two type of escaping: pairs of backslashes are
combined, and $n is a back reference to a captured (sub)pattern.
Example: To make a pure substitution without escaping effects, the
following may be used:
$subject = "xay";
$replacement = 'b\c\\d\\\e\\\\$0f\\\\\g';
// first one protects backslashes, 2nd one protects $
$aMap = array("/\\\\+/" => '$0$0', "/\\$/" =>
'\\\\$');
$rep = preg_replace(array_keys($aMap),
array_values($aMap),$replacement);
// protected replacement
$result = preg_replace("/(a)/", $rep, $subject);
// original, unprotected replacement
$res0 = preg_replace("/(a)/", $replacement, $subject);
$replacment => b\c\d\\e\\$0f\\\g
$rep => b\\c\\d\\\\e\\\\\$0f\\\\\\g
$result => xb\c\d\\e\\$0f\\\gy
$res0 => xb\c\d\e\af\\gy
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=43532&edit=1