当逗号不在任何括号内时用逗号分解字符串

Explode string with comma when comma is not inside any brackets

我有字符串 "xyz(text1,(text2,text3)),asd" 我想用 展开它,但唯一的条件是爆炸应该只发生在 , 上,它不在任何括号内(这里是 () ).

我在 Whosebug 上看到很多这样的解决方案,但它不适用于我的模式。 (example1) (example2)

我的模式的正确正则表达式是什么?

以我为例xyz(text1,(text2,text3)),asd

结果应该是

xyz(text1,(text2,text3))asd.

您可以使用带有 subroutine:

的正则表达式的匹配方法
preg_match_all('~\w+(\((?:[^()]++|(?1))*\))?~', $s, $m)

regex demo

详情

  • \w+ - 1+ 个单词字符
  • (\((?:[^()]++|(?1))*\))? - 一个可选的捕获组匹配
    • \( - 一个 (
    • (?:[^()]++|(?1))* - 零次或多次出现
      • [^()]++ - ()
      • 以外的 1+ 个字符
      • | - 或
      • (?1) - 整个第 1 组模式
    • \) - ).

PHP demo:

$rx = '/\w+(\((?:[^()]++|(?1))*\))?/';
$s = 'xyz(text1,(text2,text3)),asd';
if (preg_match_all($rx, $s, $m)) {
    print_r($m[0]);
}

输出:

Array
(
    [0] => xyz(text1,(text2,text3))
    [1] => asd
)

如果要求在 , 处拆分,但仅在嵌套括号外,另一个想法是使用 preg_split and skip the parenthesized stuff also by use of a recursive pattern.

$res = preg_split('/(\((?>[^)(]*(?1)?)*\))(*SKIP)(*F)|,/', $str);

See this pattern demo at regex101 or a PHP demo at eval.in

管道字符的左侧用于匹配和跳过括号内的内容。
在右侧,它将匹配括号外的剩余逗号。

所使用的模式是不同常见模式的变体,以匹配嵌套的括号。