Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

String concatenation in replacement of preg_replace() 2

Status
Not open for further replies.

MacTommy

Programmer
Feb 26, 2007
116
NL
This is very weird...

I have this piece of code:

Code:
<?php

$sString = "abc abc needle=567 def def";

$iNewNeedle = 123;
print preg_replace("/(needle=)[0-9]+/", ">> $1$iNewNeedle <<", $sString);

?>

It produces:
Code:
abc abc >> 23 << def def

The $1 ('needle=') part is gone, as is the first digit of $iNewNeedle...?!?

(I know that in this case I don't really need the $1, but it is just a (simple) example.)

I tried ${1}, \1 and I tried just concatenating the strings ($1 . $sNewNeedle) all of which don't work.

I am completely out of ideas here...
Does everybody experience this on their system..?!?
Is this a bug..?!?
Or am I just missing something very obvious (which usually is the case... ;-) ).

(My PHP version is 5.1.6 on RedHat Linux kernel 2.6.18)

Thanks!
 
Oh yes, and if you do ">> $1 $iNewNeedle <<" as the replacement part (with a space (or a dot, or in fact any other non-variable symbol) in between the two) it does work...?!?
 
What was the output you were hoping for?

Code:
[axtell@Axtell4 ~]$ php preg.php
abc abc >> needle=123 << def def[axtell@Axtell4 ~]$ cat preg.php
<?php

$sString = "abc abc needle=567 def def";

$iNewNeedle = 123;
print preg_replace("/(needle=)[0-9]+/", '>> ${1}'.$iNewNeedle.' <<', $sString);

?>
[axtell@Axtell4 ~]$

-----------------------------------------
I cannot be bought. Find leasing information at
 
Hi

There is nothing weird. Variable substitution is performed before the function call. So your code is the same as doing this :
Code:
[b]print[/b] [COLOR=darkgoldenrod]preg_replace[/color][teal]([/teal][green][i]"/(needle=)[0-9]+/"[/i][/green][teal],[/teal] [green][i]">> $1[highlight]123[/highlight] <<"[/i][/green][teal],[/teal] [navy]$sString[/navy][teal]);[/teal]
Which interpreted from left to right results :
[ul]
[li]literal string '>> '[/li]
[li]value of captured group $11[/li]
[li]literal string '23 <<'[/li]
[/ul]
I bet you already see the problem : the captured group reference takes up to 2 digits. I bet you already see the solution too : you have to consume all 2 digits of the captured group reference before reaching the literal '123' :
Code:
[b]print[/b] [COLOR=darkgoldenrod]preg_replace[/color][teal]([/teal][green][i]"/(needle=)[0-9]+/"[/i][/green][teal],[/teal] [green][i]">> $[highlight]0[/highlight]1$iNewNeedle <<"[/i][/green][teal],[/teal] [navy]$sString[/navy][teal]);[/teal]

Feherke.
 
damn. i puzzled over this for about 5 minutes before i realised that feherke! I wish i had seen your post before launching my test platform!
 
Feherke you are an absolute king!

This would never have occured to me anywhere in the (near) future. Thanks a lot!

That still keeps me wondering though why ${1} doesn't work (nor ${01} for that matter). I thought that actually was meant for things like this (which was why I couldn't come up with anything else).

 
Hi

MacTommy said:
That still keeps me wondering though why ${1} doesn't work (nor ${01} for that matter). I thought that actually was meant for things like this
Yes, but the braces ( {} ) only delimits the variable name to disambiguate at variable substitution time. But once the variable substitution is performed, the braces are gone and the calling function receives the string as ">> $1123 <<".

To be honest, neither I knew that escaping the sigil as ">> \${1}$iNewNeedle <<" will preserve the braces too and the regular expression will still be valid.
So thanks, jaxtell. [medal]

Feherke.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top