0

I have a string like

"first,second[,b],third[a,b[1,2,3]],fourth[a[1,2]],sixth"

I want to explode it to array

Array (
    0 => "first",
    1 => "second[,b]",
    2 => "third[a,b[1,2,3]]",
    3 => "fourth[a[1,2]]",
    4 => "sixth"
}

I tried to remove brackets:

preg_replace("/[ ( (?>[^[]]+) | (?R) )* ]/xis", 
             "",
             "first,second[,b],third[a,b[1,2,3]],fourth[a[1,2]],sixth"
); 

But got stuck one the next step

Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
abr
  • 103
  • 1
  • 14
  • You want to split the string into an array of strings using Regex? If so, check this out as a reference to [get an idea on the regex used](http://stackoverflow.com/questions/1084764/php-and-regex-split-a-string-by-commas-that-are-not-inside-brackets-and-also-n) – bonCodigo Nov 12 '12 at 16:27
  • I tried to remove brackets preg_replace("/\[ ( (?>[^\[\]]+) | (?R) )* \]/xis", "", "first,second[,b],third[a,b[1,2,3]],fourth[a[1,2]],sixth"); But got stuck one the next step – abr Nov 12 '12 at 16:27
  • You don't need a regex if you know what your delimiters look like. –  Nov 12 '12 at 16:38
  • 1
    There are CSV parsers for PHP. Download one and use it. Problem solved. Don't do this with regular expressions (simple reason: it's a waste of time because it is actually impossible to do with regular expressions). – Tomalak Nov 12 '12 at 16:39

1 Answers1

4

PHP's regex flavor supports recursive patterns, so something like this would work:

$text = "first,second[,b],third[a,b[1,2,3]],fourth[a[1,2]],sixth";

preg_match_all('/[^,\[\]]+(\[([^\[\]]|(?1))*])?/', $text, $matches);

print_r($matches[0]);

which will print:

Array
(
    [0] => first
    [1] => second[,b]
    [2] => third[a,b[1,2,3]]
    [3] => fourth[a[1,2]]
    [4] => sixth
)

The key here is not to split, but match.

Whether you want to add such a cryptic regex to your code base, is up to you :)

EDIT

I just realized that my suggestion above will not match entries starting with [. To do that, do it like this:

$text = "first,second[,b],third[a,b[1,2,3]],fourth[a[1,2]],sixth,[s,[,e,[,v,],e,],n]";

preg_match_all("/
    (             # start match group 1
      [^,\[\]]    #   any char other than a comma or square bracket
      |           #   OR
      \[          #   an opening square bracket
      (           #   start match group 2
        [^\[\]]   #     any char other than a square bracket
        |         #     OR
        (?R)      #     recursively match the entire pattern
      )*          #   end match group 2, and repeat it zero or more times
      ]           #   an closing square bracket
    )+            # end match group 1, and repeat it once or more times
    /x", 
    $text, 
    $matches
);

print_r($matches[0]);

which prints:

Array
(
    [0] => first
    [1] => second[,b]
    [2] => third[a,b[1,2,3]]
    [3] => fourth[a[1,2]]
    [4] => sixth
    [5] => [s,[,e,[,v,],e,],n]
)
Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
  • Thank you! No decryption is needed - this just has to work correctly. And it does) – abr Nov 12 '12 at 17:04