Page 1 of 1

[SOLVED] - preg_replace() confusion in pattern

Posted: Fri Mar 11, 2005 2:08 am
by anjanesh
Im getting stuck at this simple problem with preg_replace().
Im trying to remove whatever comes in beteen ', ' and ');

Code: Select all

<?php
$string = "function('test1', 'test2');";
$pattern = "/(', ')*?('\);)/i";
$replacement = "";
echo preg_replace($pattern, $replacement, $string);
?>
The output I want is function('test1', ''); but this is not working.
Any Ideas ?
Thanks

Re: preg_replace() confusion in pattern

Posted: Fri Mar 11, 2005 2:28 am
by Chris Corbyn
You weren't putting back the bits you'd stored off, and you'd missed the dot before the * to get all chars. This one allows for the whitespace where you'd sometimes find it too...

Code: Select all

<?php
$string = "function('test1', 'test2');";
$pattern = '/(\'\s?\,\s?\').*?(\'\s?\);)/';
$replacement = "$1$2";
echo preg_replace($pattern, $replacement, $string);
?>
:wink:

Posted: Fri Mar 11, 2005 2:42 am
by anjanesh
Thanks d11. I wanted to figure out abt whitespace chars too but couldnt. Your code really helped.
BTW, is there any good tutorial explaining preg_match, preg_replace esp pattern syntax ?
http://www.php.net/manual/en/reference. ... syntax.php just one huge reference.
Thanks

Posted: Fri Mar 11, 2005 2:47 am
by Chris Corbyn
I just learnt regexp's in a different language (Perl) and carried that knowledge into PHP so in short... I'm not sure where there are any. But I can post a link to a good site for explaining regexp's in general, including search & replace (essentially preg_replace() ).

http://www.regular-expressions.info/

The above link may helps to explain all the pattern syntax and stuff. You just need to adapt it into the PHP functions :wink:

There's probably better sites out there but this is just one I used recently to refresh my memory on some things.

Posted: Fri Mar 11, 2005 7:22 am
by anjanesh
Again I seemed to be confused ? This time I though I got what you did but this is not producing test1

Code: Select all

<?php
$string = "function('test1', 'test2');";
$pattern = '/(function\s?\(\s?\').*?(\'\s?\,\s?\')/i';
preg_match($pattern,$string,$matches);
echo $matches[2];
?>

Posted: Fri Mar 11, 2005 7:30 am
by Chris Corbyn
You want it to just display the word 'test1' now? If I've misunderstood you please say ;)

Code: Select all

<?php
$string = "function('test1', 'test2');";
$pattern = '/function\s?\(\s?\'(.*?)\'\s?\,\s?\'.*?\'\s?\);/i';
preg_match($pattern,$string,$matches);
echo $matches[1];
?>
EDIT: Dont worry about not understanding them really quickly ananjesh... they can take a while and then it suddenly clicks and all seems to make sense.

You just need to look at load, see what they do and then play with them and see what the changes do to it. If I'm gonna do a regexp that I think will be tricky I gradually increase it's complexity. So for this case I'd maybe start with a very simple regexp that simply picks out the word 'function', then if it works move on. Next I'd make it read right the way up until the first " ' ". If that works you know the next bit is what you need to extract. So you'd write some ( ) then put the patter to extract. Here that is just .* (any cahracter, any number of times). Then you see you've successfully extracted "test1', 'test2'); ". Next, tell it where to stop extracting (the quote) " ' ".... etc etc etc... Just start it simple and build it up is what I'm saying. Test it each time you make a change.

Posted: Fri Mar 11, 2005 7:45 am
by anjanesh
No d11 - you got it right.
In the first code you posted you used (...).*?(...) while in the second one is ...(...(...)...)
When do we use () and hows it different in the code you posted above. The first one replaces test2 while the second one searches for test1. Why is the pattern structure so different ?
The reason why Im asking is I tried managing something by looking at some examples in php.net and came up with which was giving the output test1 but I knew this one wouldnt search for extra whitespaces in between. Thats why I asked this q.

Code: Select all

preg_match("/(define\(')?([^', ']+)/i",$string,$matches);
echo $matches[2]; // Produces test1
My index result is in array element 2 while yours is in 1 ???

Posted: Fri Mar 11, 2005 7:57 am
by Chris Corbyn
Look closer at the second one.

The first and last parens are escaped \( and \) since they are part of the string we were searching. So you'll see that therefore the only parens for extraction are the inner ones. This represents $1 (or $matches[1] in preg_match() ).
Note: $matches[0] is the whole string.

The structure of the second one is not actually much different if you break it down (apart from the specification the word 'function')

Posted: Fri Mar 11, 2005 8:01 am
by Chris Corbyn
The reason your index is 2 BTW is due to the nesting you have of your parens'.

If you nest ( ) then it takes the outer ones as "1" then the next as "2" etc.

If I remember correctly it goes like this... (I'll have to test to be certain).

"(this is $1 (this is $2 (this is $3) ) ) (this is $4 (this is $5) )" kind thing.

You also ask about when you should use (..). They have several uses. Mainly being:

1. To group charcters/patterns together
2. To specify part of the pattern to extract.

Remember that if you have (..) even if it's not your intention to extract that part, you need to account for it's presence when you specifiy the index of the part you're extracting.

PM me and I can post you some docs etc. feyd is the RegExp master in here however - he's the daddy ;-)

Posted: Sat Mar 12, 2005 9:36 am
by anjanesh
Thanks d11 for your detailed explanation.
Im finally getting the hang of it now.

Posted: Sat Mar 12, 2005 9:41 am
by Chris Corbyn
No worries. It all falls into place eventually.

Good luck!