Doc #64516 [Ver->Csd]: preg_quote() doesn't work to escape the replacement

From: Date: Sat, 20 Aug 2016 13:02:29 +0000
Subject: Doc #64516 [Ver->Csd]: preg_quote() doesn't work to escape the replacement
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-13845@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=64516&edit=1

 ID:                 64516
 Updated by:         cmb@php.net
 Reported by:        php at richardneill dot org
 Summary:            preg_quote() doesn't work to escape the replacement
-Status:             Verified
+Status:             Closed
 Type:               Documentation Problem
 Package:            PCRE related
 Operating System:   all
 PHP Version:        5.4.13
 Assigned To:        cmb
 Block user comment: N
 Private report:     N



Previous Comments:
------------------------------------------------------------------------
[2016-08-20 13:02:11] cmb@php.net

Automatic comment from SVN on behalf of cmb
Revision: http://svn.php.net/viewvc/?view=revision&revision=339916
Log: Fix #64516: preg_quote() doesn't work to escape the replacement

------------------------------------------------------------------------
[2016-08-20 12:41:14] cmb@php.net

In my opinion, there is no need for preg_quote_replacement() to be
in the core, because it appears to be rarely needed, and can
otherwise easily implemented in userland:

function preg_quote_replacement($str) {
    return addcslashes($str, '\\$');
}

See also <https://3v4l.org/ZYue6>.

I agree, that the documentation should be improved to point out
that preg_quote() shouldn't be used on replacement strings.

------------------------------------------------------------------------
[2013-03-25 22:30:06] php at richardneill dot org

Description:
------------
preg_quote() is great for escaping a user-supplied search string.
There is no matching function to escape a user-supplied replacement string.

My wish is for preg_quote() to have an extra flag "IS_REPLACEMENT" or to have a 
function preg_quote_replacement(), which would escape only backslash and dollar 
signs.

Example below.


Might I also suggest this is a documentation bug, in that there is no explanation 
of the correct way to work around this?

Test script:
---------------
$text = 'Invoice: You owe me *#5* !';
$user_search  = "*#5*";
$user_replace = "*$5*";

$search = preg_quote($user_search, "/");
$replace_bad1 = $user_replace;
$replace_bad2 = preg_quote($user_replace);  

$new_text1 = preg_replace("/$search/", "$replace_bad1", $text);
$new_text2 = preg_replace("/$search/", "$replace_bad2", $text);
echo "Input: $text\nNew1:  $new_text1\nNew2:  $new_text2\n";


Expected result:
----------------
I want to return the string:
    Invoice: You owe me *$5* !


Actual result:
--------------
Input: Invoice: You owe me *#5* !
New1:  Invoice: You owe me ** !
New2:  Invoice: You owe me \*$5\* !

1. the '*' in the search string is not magic, thanks to the normal use of 
preg_quote(). This is what I expect.

2. If I replace with a literal, then '$5' becomes the 5th backreference, which is 
empty.

3. If I preg_quote the replacement, then we get spurious backslashes before the 
'*'s.


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



--
Edit this bug report at https://bugs.php.net/bug.php?id=64516&edit=1


Thread (2 messages)

« previous php.doc.bugs (#13845) next »