Edit report at https://bugs.php.net/bug.php?id=61214&edit=1
ID: 61214 Comment by: 58219758 at qq dot com Reported by: 58219758 at qq dot com Summary: puzzled replace when replacement contains "=" Status: Not a bug Type: Bug Package: PCRE related Operating System: windows 7 PHP Version: 5.3.10 Block user comment: N Private report: N New Comment: Thank you very much! Previous Comments: ------------------------------------------------------------------------ [2012-03-01 18:04:06] anon at anon dot anon This is happening because of the fourth search expression /\w+\=([^=]+)/. It matches the previous replacements and removes them. Without it, this: echo preg_replace( array('/required/', '/min\=(\d+)/', '/max\=(\d+)/'), array('R=1', 'R="$1"', 'R="$1"'), 'required min=3 max=5 code=code' ) . "\n"; Outputs: R=1 R="3" R="5" code=code (As expected.) But the replacements happen one after the other instead of simultaneously, so then it will do the equivalent of this: echo preg_replace( '/\w+\=([^=]+)/', '', 'R=1 R="3" R="5" code=code' ) . "\n"; ..which will match and remove 'R=1 R' and 'R="5" code', producing the "puzzling" output: ="3" =code Here is one way to solve it, by doing all the matches simultaneously with one regexp: echo preg_replace_callback( '/(\w+)(?:=(\S+))?/', function ($parts) { if (!empty($parts[2])) { // have '=' if ($parts[1] == 'min' || $parts[1] == 'max') { return 'R="' . $parts[2] . '"'; } else { return ''; } } else { if ($parts[1] == 'required') { return 'R=1'; } else { return $parts[0]; // unmodified } } }, 'required min=3 max=5 code=code' ) . "\n"; This outputs: R=1 R="3" R="5" ------------------------------------------------------------------------ [2012-03-01 10:03:08] 58219758 at qq dot com $search = array( '/required/', '/min\=(\d+)/', '/max\=(\d+)/', '/\w+\=([^=]+)/', ); $replace2 = array( 'R=1', 'R="$1"', 'R="$1"', ); in this case, the result is still ="3" =code ------------------------------------------------------------------------ [2012-03-01 09:59:23] 58219758 at qq dot com "=" will be quoted to "\=", in this case, the result is R\=1 R\="3" R\="5" too, whenever "\=" or "\\=". ------------------------------------------------------------------------ [2012-03-01 08:35:04] ras...@php.net This is not a bug. '=' has special meaning in ?= and ?<= expressions and it is on the list of characters quotes by preg_quote. ------------------------------------------------------------------------ [2012-03-01 08:25:13] 58219758 at qq dot com Description: ------------ $search = array('/required/','/min\=(\d+)/','/max\=(\d+)/','/\w+\=([^=]+)/',); $replace2 = array('R=1','R="$1"','R="$1"',); It seems doesn't work correctly when replacement contains "=" Test script: --------------- $search = array('/required/','/min\=(\d+)/','/max\=(\d+)/','/\w+\=([^=]+)/',); $replace1 = array('R1','R"$1"','R"$1"',); $replace2 = array('R=1','R="$1"','R="$1"',); $replace3 = array('R\\=1','R\\="$1"','R\\="$1"',); $from = 'required min=3 max=5 code=code'; echo preg_replace($search, $replace1, $from); echo preg_replace($search, $replace2, $from); echo preg_replace($search, $replace3, $from); Expected result: ---------------- R1 R"3" R"5" R=1 R="3" R="5" R\=1 R\="3" R\="5" Actual result: -------------- R1 R"3" R"5" ="3" =code R\=1 R\="3" R\="5" ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=61214&edit=1