PHP:在逗号上拆分字符串,但不是在大括号或引号之间?

Dyl*_*lan 7 php regex split preg-match-all

在PHP中,我有以下字符串:

$str = "AAA, BBB, (CCC,DDD), 'EEE', 'FFF,GGG', ('HHH','III'), (('JJJ','KKK'), LLL, (MMM,NNN)) , OOO"; 
Run Code Online (Sandbox Code Playgroud)

我需要将此字符串拆分为以下部分:

AAA
BBB
(CCC,DDD)
'EEE'
'FFF,GGG'
('HHH','III')
(('JJJ','KKK'),LLL, (MMM,NNN))
OOO
Run Code Online (Sandbox Code Playgroud)

我尝试了几个正则表达式,但找不到解决方案.有任何想法吗?

UPDATE

我决定使用正则表达式并不是最好的解决方案,在处理格式错误的数据,转义报价等时.

感谢在这里提出的建议,我找到了一个使用解析的函数,我根据自己的需要重写了这个函数.它可以处理不同类型的支架,分隔符和报价也是参数.

 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;
  }
Run Code Online (Sandbox Code Playgroud)

Bar*_*ers 8

而不是a preg_split,做一个preg_match_all:

$str = "AAA, BBB, (CCC,DDD), 'EEE', 'FFF,GGG', ('HHH','III'), (('JJJ','KKK'), LLL, (MMM,NNN)) , OOO"; 

preg_match_all("/\((?:[^()]|(?R))+\)|'[^']*'|[^(),\s]+/", $str, $matches);

print_r($matches);
Run Code Online (Sandbox Code Playgroud)

将打印:

Array
(
    [0] => Array
        (
            [0] => AAA
            [1] => BBB
            [2] => (CCC,DDD)
            [3] => 'EEE'
            [4] => 'FFF,GGG'
            [5] => ('HHH','III')
            [6] => (('JJJ','KKK'), LLL, (MMM,NNN))
            [7] => OOO
        )

)

正则表达式\((?:[^()]|(?R))+\)|'[^']*'|[^(),\s]+可以分为三个部分:

  1. \((?:[^()]|(?R))+\),匹配平衡的括号对
  2. '[^']*' 匹配带引号的字符串
  3. [^(),\s]+它匹配不包括任何字符序列'(',')',','或空白字符