0

I am trying to explode / preg_split a string so that I get an array of all the values that are enclosed in ( ). I've tried the following code but I always get an empty array, I have tried many things but I cant seem to do it right

Could anyone spot what am I missing to get my desired output?

$pattern = "/^\(.*\)$/";
$string = "(y3,x3),(r4,t4)";
$output = preg_split($pattern, $string);
print_r($output);

Current output Array ( [0] => [1] => )

Desired output Array ( [0] => "(y3,x3)," [1] => "(r4,t4)" )

Delimitry
  • 2,987
  • 4
  • 30
  • 39
Jonathan Thurft
  • 4,087
  • 7
  • 47
  • 78
  • Is it necessary in your situation to have ^ and $ in your regex? I tried with an Ungreedy group catching version of your regex.. have a look here http://regex101.com/r/fL6pN5/1 – lcoderre Jul 03 '14 at 20:15
  • You have to use `preg_match_all`, not `preg_split` – hindmost Jul 03 '14 at 20:17
  • @Jonathan Thurft it's important to mention that the usage of lookbehind and lookahead impacts on the performance. For a js performance test you can check it [here](http://jsperf.com/test-regex-so-24562713) – Federico Piazza Jul 04 '14 at 20:54

2 Answers2

4

With preg_split() your regex should be matching the delimiters within the string to split the string into an array. Your regex is currently matching the values, and for that, you can use preg_match_all(), like so:

$pattern = "/\(.*?\)/";
$string = "(y3,x3),(r4,t4)";
preg_match_all($pattern, $string, $output);
print_r($output[0]);

This outputs:

Array 
( 
    [0] => (y3,x3) 
    [1] => (r4,t4) 
)

If you want to use preg_split(), you would want to match the , between ),(, but without consuming the parenthesis, like so:

$pattern = "/(?<=\)),(?=\()/";
$string = "(y3,x3),(r4,t4)";
$output = preg_split($pattern, $string);
print_r($output);

This uses a positive lookbehind and positive lookahead to find the , between the two parenthesis groups, and split on them. It also output the same as the above.

nickb
  • 59,313
  • 13
  • 108
  • 143
2

You can use a simple regex like \B,\B to split the string and improve the performance by avoiding lookahead or lookbehind regex.

\B is a non-word boundary so it will match only the , between ) and (

Here is a working example:

http://regex101.com/r/cV7bO7/1

$pattern = "/\B,\B/";
$string = "(y3,x3),(r4,t4),(r5,t5)";
$result = preg_split($pattern, $string);

$result will contain:

Array
(
    [0] => (y3,x3)
    [1] => (r4,t4)
    [2] => (r5,t5)
)
Federico Piazza
  • 30,085
  • 15
  • 87
  • 123