PHP: dividir string na vírgula, mas NÃO quando entre chaves ou aspas?
No PHP eu tenho a seguinte string:
$str = "AAA, BBB, (CCC,DDD), 'EEE', 'FFF,GGG', ('HHH','III'), (('JJJ','KKK'), LLL, (MMM,NNN)) , OOO";
Eu preciso dividir essa string nas seguintes partes:
AAA
BBB
(CCC,DDD)
'EEE'
'FFF,GGG'
('HHH','III')
(('JJJ','KKK'),LLL, (MMM,NNN))
OOO
Eu tentei vários regexes, mas não consegui encontrar uma solução. Alguma ideia?
ATUALIZAR
Eu decidi usar regex não é realmente a melhor solução, ao lidar com dados malformados, citações de escape, etc.
Graças a sugestões feitas aqui, encontrei uma função que usa a análise, que reescrevi para atender às minhas necessidades. Ele pode lidar com diferentes tipos de suportes e o separador e aspas também são 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;
}