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

时间:2018-03-13 17:20:51

标签: regex preg-replace

我有字符串“xyz(text1,(text2,text3)),asd”我想用它进行爆炸,但唯一的条件是爆炸只应发生在cd ..不在任何括号内(此处)它是,)。

我在stackoverflow上看到了很多这样的解决方案,但它对我的模式不起作用。 (example1)(example2

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

就我而言()

结果应该是

xyz(text1,(text2,text3)),asdxyz(text1,(text2,text3))

2 个答案:

答案 0 :(得分:1)

您可以使用带有subroutine的正则表达式的匹配方法:

preg_match_all('~\w+(\((?:[^()]++|(?1))*\))?~', $s, $m)

请参阅regex demo

<强>详情

  • \w+ - 1 + word chars
  • (\((?:[^()]++|(?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
)

答案 1 :(得分:1)

如果要求是在,分割但仅在嵌套括号外部,则另一个想法是使用preg_splitskip括号内的东西也可以使用recursive pattern

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

See this pattern demo at regex101PHP demo at eval.in

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

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