views:

280

answers:

2

(first time poster, long time visitor via Google)

I'm trying to extract the contents of some square brackets, however i'm having a spot of bother. I've got it working for round brackets as seen below, but I can't see how it should be modified to work for square brackets. I would have thought replacing the round for square and vice versa in this example should work, but apparently not.

It needs to ignore brackets within brackets. So it won't return (11) but will return (10(11)12).

$preg = '#\(((?>[^()]+)|(?R))*\)#x';
$str = '123(456)(789)(10(11)12)';

if(preg_match_all($preg, $str, $matches)) {
    $matches = $matches[0];
} else {
    $matches = array();
}

echo '<pre>'.print_r($matches,true).'</pre>';

This returns:

Array (
    [0] => (456)
    [1] => (789)
    [2] => (10(11)12)
)

Which is perfect. However, how can I get this working for a string with square brackets instead e.g:

$str = '123[456][789][10[11]12]'; 
+6  A: 
$preg = '#\[((?>[^\[\]]+)|(?R))*\]#x';
Lucero
That doesn't appear to work either, unless my test code is wrong somewhere. Here's the code and the response:<pre> $preg = '/\[(?:[^\[\]]+¦(?R))*\]/'; $str = '123[456][789][10[11]12]'; if($count = preg_match_all($preg, $str, $matches)) { $matches = $matches[0]; } else { $matches = array(); } echo $count.'<pre>'.print_r($matches,true).'</pre>';</pre>Returns:<pre>0Array()</pre>
Rob
I get an error with this `(?R))*` on PCRE?
Alix Axel
@Alix Axel: It is composed of `(?R)` and the `)*` on the end is a part of the larger expression.
Bandi-T
I copy-pasted your sample and modified the parts necessary to handle the other braces. However, as you must have seen in the meantime (you fixed it), the code sample of yours had the wrong pipe character.
Lucero
This regex works for me. Testing it at http://www.spaweditor.com/scripts/regex/ yields exactly the result I expect.
Alan Moore
Thanks that's perfect now. Sorry about the late reply. End of the day over here. For anyone finding this in the future, I don't know if it could be improved performance wise by making sure it only returns the one array, rather than the second as well. But apart from that perfect, answer accepted.
Rob
A: 

Try this:

$str = '123[456][789][10[11]12]';
$pattern = '/(([\d]+)|(\[[\d]+\])|\[[\d\[\]]+\])/';
preg_match_all($pattern,$str,$matches);
print_r($matches[0]);
//or
$str = '123[456][789][10[11]12]';
$pattern = '/(([\d]+)|(\[[\d]+\]))/';
preg_match_all($pattern,$str,$matches);
print_r($matches[0]);
Thanks for this, but the first one appears to be limited to a certain depth. For instance try this: [123][456][789][10[11]12][141516][somethingelse].The second one seperates nested brackets out. So doesn't work at all in that regard.
Rob