PHP: división de la cadena en coma, pero ¿NO cuando entre llaves o comillas?
En PHP tengo la siguiente cadena:
$str = "AAA, BBB, (CCC,DDD), 'EEE', 'FFF,GGG', ('HHH','III'), (('JJJ','KKK'), LLL, (MMM,NNN)) , OOO";
Necesito dividir esta cadena en las siguientes partes:
AAA
BBB
(CCC,DDD)
'EEE'
'FFF,GGG'
('HHH','III')
(('JJJ','KKK'),LLL, (MMM,NNN))
OOO
Probé varias expresiones regulares, pero no pude encontrar una solución. ¿Algunas ideas?
ACTUALIZAR
Decidí que usar Regex no es realmente la mejor solución, cuando se trata de datos mal formados, citas escapadas, etc.
Gracias a las sugerencias hechas aquí, encontré una función que utiliza el análisis, que reescribí para satisfacer mis necesidades. Puede manejar diferentes tipos de soportes y el separador y la cita también son parámetros.
function explode_brackets($str, $separator=",", $leftbracket="(", $rightbracket=")", $quote="'", $ignore_escaped_quotes=true ) {
$buffer = '';
$stack = array();
$depth = 0;
$betweenquotes = false;
$len = strlen($str);
for ($i=0; $i<$len; $i++) {
$previouschar = $char;
$char = $str[$i];
switch ($char) {
case $separator:
if (!$betweenquotes) {
if (!$depth) {
if ($buffer !== '') {
$stack[] = $buffer;
$buffer = '';
}
continue 2;
}
}
break;
case $quote:
if ($ignore_escaped_quotes) {
if ($previouschar!="\\") {
$betweenquotes = !$betweenquotes;
}
} else {
$betweenquotes = !$betweenquotes;
}
break;
case $leftbracket:
if (!$betweenquotes) {
$depth++;
}
break;
case $rightbracket:
if (!$betweenquotes) {
if ($depth) {
$depth--;
} else {
$stack[] = $buffer.$char;
$buffer = '';
continue 2;
}
}
break;
}
$buffer .= $char;
}
if ($buffer !== '') {
$stack[] = $buffer;
}
return $stack;
}