Correct way to split nested brackets in PHP, e.g. "root[one[a,b,c],two[d,e,f]]" into array? -


like title says i'm looking robust way parse expression array (example in code).

<?php  $str = 'root[one[a,b,c],two[d,e,f]]' $decoded = decode($str); 

output:

$decoded = ['root' => ['one' => ['a', 'b', 'c'], 'two' => ['d', 'e', 'f']] 

i'm trying via regex since brackets , commas nested it's not yielding correct results. how can this?

a simple parser below should job. did not test - successful route, , few obvious edge cases based on fair assumptions.

var_dump(parse('root[one[a,b,c],two[d,e,f]]'));  function parse($str, $level = 0) {     if ($level === 0) {         // strip spaces once simplicity         $str = str_replace([" ", "\t"], '', $str);     }     $result = [];     while(true) {         $rest = strpbrk($str, '[],');         if (!$rest) {             if (strlen($str) > 0) {                 throw new expectedendofstringexception($str);             }             return $result;         }         $term = substr($rest, 0, 1);         $rest = substr($rest, 1);         $val = substr($str, 0, strpos($str, $term));         switch ($term) {             case '[':                 if (!$val) {                     $val = 0;                 } elseif (isset($result[$val])) {                     throw new nonuniquekeyexception($val);                 }                 list($a, $str) = parse($rest, $level+1);                 if (is_null($a) && is_null($str)) {                     throw new bracketsmismatchexception($rest);                 }                 $result = array_merge($result, [$val => $a]);                 break;             case ']':                 if ($val) {                     $result[] = $val;                 }                 if($level < 1) {                     throw new bracketsmismatchexception($rest);                 }                 if (strlen($rest) > 0 && !in_array(substr($rest, 0, 1), [',', ']'])) {                     throw new malformedstringexception($val.$term.$rest);                 }                 return [$result, ltrim($rest, ',')];             case ',':                 if (!$val) {                     throw new unexpectedcomaexception($term.$rest);                 }                 $result[] = $val;                 $str = $rest;                 break;             default:                 throw new logicexception();         }     } } 

http://sandbox.onlinephpfunctions.com/code/d1e74494226d530d1ed5b3c2d0fd7d545acb2d9e

you need implement exception classes, should trivial. otherwise replace them generic \exception();


Comments

Popular posts from this blog

javascript - Laravel datatable invalid JSON response -

java - Exception in thread "main" org.springframework.context.ApplicationContextException: Unable to start embedded container; -

sql server 2008 - My Sql Code Get An Error Of Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value '8:45 AM' to data type int -