0

I want to split by comma inside braces except another braces inside braces

$q1 ="CREATE TABLE notes(id INTEGER,code DECIMAL (4,2),PRIMARY KEY (id))";
$q2 ="CREATE TABLE notes(id INTEGER,code TEXT)";

$r = preg_split('/\([^()]*\)(*SKIP)(*F)|[()]|,/', $q1);//$q1 splitted but $q2 no
print_r($r);

The final result should be:

for $q1 :

   array(
         0 => id INTEGER
         1 => code DECIMAL (4,2)
         2 => PRIMARY KEY (id)
   );

for $q2 :

   array(
        0 => id INTEGER
        1 => code TEXT
   );
ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
edd
  • 64
  • 8

2 Answers2

1

Code: (PHP Demo)

$sqls = array(
    "CREATE TABLE notes(id INTEGER,code DECIMAL (4,2),PRIMARY KEY (id))",
    "CREATE TABLE notes(id INTEGER,code TEXT)"
);

foreach($sqls as $sql){
    if(preg_match_all("/(?:^.+?\(|,)(?:\K[\w ]+(?:\([\S].*?\))?)/", $sql,$matches)){
        echo "<pre>";
            var_export($matches[0]);
        echo "</pre>";
    }
}

Output:

// first $matches...
array(
    0 => 'id INTEGER',
    1 => 'code DECIMAL (4,2)',
    2 => 'PRIMARY KEY (id)'
)
// second $matches...
array(
    0 => 'id INTEGER',
    1 => 'code TEXT'
)

Regex Breakdown: (Regex Demo)

(?:^.+?\(|,)          #group everything from the start to 1st parenthesis or a comma
(?:\K[\w ]+           #\K means "only retain text from this point", group words and spaces
    (?:\([\S].*?\))?  #optionally group parenthetical text
)

Using \K permits the exclusion of a capture group and preg_match_all returns the desired string (full string) in the first subarray. The benefit is a $matches array that half the size of an array with a capture group.

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • @edd If my answer satisfies, please award it the green tick. Otherwise please leave me a comment that explains what remains to be fixed. – mickmackusa Mar 28 '17 at 17:05
0

If embeded parenthesis contain only digits, this does the job:

$sqls = array(
"CREATE TABLE notes(id INTEGER,code DECIMAL (4,2),PRIMARY KEY (id))",
"CREATE TABLE notes(id INTEGER,code TEXT)"
);

foreach ($sqls as $sql) {
    $arr = preg_split("/(?<!\d)[(),](?!\d)/", $sql);
    print_r($arr);
}

Output:

Array
(
    [0] => CREATE TABLE notes
    [1] => id INTEGER
    [2] => code DECIMAL (4,2)
    [3] => PRIMARY KEY 
    [4] => id
    [5] => 
    [6] => 
)
Array
(
    [0] => CREATE TABLE notes
    [1] => id INTEGER
    [2] => code TEXT
    [3] => 
)
Toto
  • 89,455
  • 62
  • 89
  • 125