Jump to content

Referencing named groups in preg_replace


DarkWater

Recommended Posts

Hey everyone. Well, I'm pretty proficient in regular expressions, and I stumbled upon a little problem that I really couldn't find a solution to (but then again, I didn't search too hard, hoping someone here would know. ;) )  Here we go:

 

Let's say I had this regex:

/^(?<!\$)(?P<word>\w+)$/

 

It tests to make sure that a string doesn't start with a $ and contains only word characters.  Simple enough, right?  Well, I was just playing around with named capture groups to see how PHP handles them.  It seems that they're added as an associative array key to the matches array:

<?php
$str = 'testing';
$matches = array();
echo preg_match('/^(?<!\$)(?P<word>\w+)$/', $str, $matches);
echo "\n";
print_r($matches);
?>

 

Outputs:

Array
(
    [0] => testing
    [word] => testing
    [1] => testing
)

 

Now, how would you reference that named capture in preg_replace() without using the numbered reference?  I know that you can use it inside the regex for backreferencing with (?P=word).  >_>  Anyone want to throw some advice out there? xD

Link to comment
Share on other sites

I cannot find any information on this. My assumption is that it doesn't exist because there isn't a need for it. A data structure is being built when matching, so it's nice to be able to customize the key, whereas replacing is solely done by the engine.

 

In the event that your replaces get nasty, the best approach is to use the /x modifier:

/

### 1. Name

(...)

### 2. Address

(...)

### 3. And so forth...

(...)

/x

Link to comment
Share on other sites

Yeah, I've used free spacing before for comments and stuff.  Thanks though.  Although, I think I read somewhere that in 5.2.4 you can use:

\k<name>, \k'name', \k{name} or \g{name}

 

To reference your named capture groups.  Not sure if it would work in preg_replace() though.  I'll need to go test it later. >_< 

 

Found it on this page

Link to comment
Share on other sites

Okay, apparently those don't work in preg_replace() either, but I do see where you're coming from, effigy.  Guess that won't work, lol.  But it IS handy to have in preg_match().

 

Btw, if someone does know how to do this, please say so.  And to avoid any confusion, I'll say before hand that I changed the regex to:

/\b(?<!\$)(?P<word>\w+)\b/

 

Lets me get any words that don't have a $ at the start from a string.

Just to see how preg_match_all() handled named groups.  Same as preg_match_all() always handles things; just a multi-dimensional array with the capture group's name included as one of the keys, which is pretty good to know.

Link to comment
Share on other sites

Well, I looked it up in the mastering regular expressions book.. it seems that in every instance of named captures, it always involves preg_match only. So perhaps it is only usable with this function? I could not find anything in the php.net manual (unless I'm just searching for the incorrect terms).

 

::shrug::

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.