#18442 [Opn->Csd]: Numbered backreferences don't work properly
| From: | andrei@php.net | Date: | Wed, 11 Sep 2002 14:44:09 +0000 |
| Subject: | #18442 [Opn->Csd]: Numbered backreferences don't work properly | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-19041@lists.php.net to get a copy of this message | ||
ID: 18442
Updated by: andrei@php.net
Reported By: joeasdf@hotmail.com
-Status: Open
+Status: Closed
Bug Type: PCRE related
Operating System: Win2K (NT 5.0 build 2195)
PHP Version: 4.2.1
Assigned To: andrei
New Comment:
I added the ability to use Perl-style ${n} references. This should take
care of your problem.
Previous Comments:
------------------------------------------------------------------------
[2002-07-22 18:16:52] joeasdf@hotmail.com
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
------------------------------------------------------------------------
[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