php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #43532 preg_replace: Escaping \ and $n in 2nd arg
Submitted: 2007-12-08 02:03 UTC Modified: 2008-11-07 14:42 UTC
From: csaba at alum dot mit dot edu Assigned:
Status: Closed Package: Documentation problem
PHP Version: Irrelevant OS:
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: csaba at alum dot mit dot edu
New email:
PHP Version: OS:

 

 [2007-12-08 02:03 UTC] 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


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-12-08 09:51 UTC] 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 12:28 UTC] csaba at alum dot mit dot edu
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.)
 [2008-11-07 14:42 UTC] vrana@php.net
This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation better.

"To use backslash in replacement, it must be doubled("\\\\" PHP string)."
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon May 06 18:01:35 2024 UTC