Bug #18442 Updated: Numbered backreferences don't work properly

From: Date: Mon, 22 Jul 2002 22:16:53 +0000
Subject: Bug #18442 Updated: Numbered backreferences don't work properly
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-14805@lists.php.net to get a copy of this message
ID: 18442 Updated by: joeasdf@hotmail.com Reported By: joeasdf@hotmail.com Status: Open Bug Type: PCRE related Operating System: Win2K (NT 5.0 build 2195) PHP Version: 4.2.1 New Comment: The reason I can't use substr is because I am parsing strings of arbitrary length, where one or more dates of this format may appear. I posted the simplest script/example I could to describe the bug without adding anything extra to detract from it. Take care, nik Previous Comments: ------------------------------------------------------------------------ [2002-07-20 07:55:56] leblanc@anywhere.com and what about doing : $repl=substr($text,3,2).substr($text,0,2)."01"; ?? this would be much faster imo. For that case I dun see the need for a regular exp heh /Leblanc ------------------------------------------------------------------------ [2002-07-19 19:54:56] joeasdf@hotmail.com I want to reformat a date string from mm/yy to yymmdd (e.g. replace "67/89" with "896701". The problem is that I need to be able to separate my numbered backreferences but NOT separate the output text. In perl, this would be written as "${2}${1}01", but PHP does not allow curly braces in the numbered reference. $text = '67/89'; $patt = '!(\d\d)/(\d\d)(?=\t)!'; $repl = '{$2}${1}01'; echo preg_replace($patt, $repl, $text); // outputs "{89}${1}01" The PHP manual for preg_replace says that numbered backreferences work for numbers from 0 - 99, so I figured I'd try two-digit backreference numbers to force the separation between $1 and 01: $repl = '$02$0101'; Here's where the real bug lies -- $02 is substituted properly, but the 2 and 1 are still inserted into the output! Only '$0' is removed from the replacement pattern: echo preg_replace($patt, $repl, $text); // outputs "89267101" The third character, 2, is the 2nd digit of $02. Similarly, the 1 immediately following 67 is from $01. The only way to get around this problem is to use preg_match() and manually create the string using the $matches array. if(preg_match('(.*)' . $patt . '(.*)', $text, $matches)) { $text = $matches[1]; // everything before $patt $text .= $matches[3]; // our old $2 $text .= $matches[2]; // our old $1 $text .= '01'; // from the original replacement $text .= $matches[4]; // everything after $patt } Seems a huge waste... Take care, nik ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=18442&edit=1

« previous php.bugs (#14805) next »