perl正则表达式获取不在括号或嵌套括号中的逗号

perl regex to get comma not in parenthesis or nested parenthesis

我有一个逗号分隔的字符串,我想匹配每个不在括号中的逗号(保证括号是平衡的)。

a   ,   (b)  ,   (d$_,c)    ,     ((,),d,(,))

a和(b)、(b)和(d$,c)、(d$,c)和((,),d,( ,)) 应该匹配但不在 (d$_,c) 或 ((,),d,(,)) 内。

注意:最终我想用这些逗号分割字符串。

它尝试了这个正则表达式: (?!<(?:\(|\[)[^)\]]+),(?![^(\[]+(?:\)|\])) 来自 但它仅适用于非嵌套括号。

您可以使用

(\((?:[^()]++|(?1))*\))(*SKIP)(*F)|,

regex demo

详情

  • (\((?:[^()]++|(?1))*\)) - 捕获组 1:匹配平衡括号之间的子字符串:
    • \( - 一个 ( 字符
    • (?:[^()]++|(?1))* - 除了 () 之外的 1+ 个字符或整个第 1 组模式(由于 regex subroutine (?1) 这是必需的,因为整个正则表达式模式中只有一部分是递归的)
    • \) - 一个 ) 字符。
  • (*SKIP)(*F) - 省略找到的匹配项并从匹配项的末尾开始下一次搜索
  • | - 或
  • , - 匹配嵌套括号外的逗号。

用于此的单个正则表达式非常复杂并且难以维护或扩展。这是一个迭代解析器方法:

use strict;
use warnings;

my $str = 'a   ,   (b)  ,   (d$_,c)    ,     ((,),d,(,))';

my $nesting = 0;
my $buffer = '';
my @vals;
while ($str =~ m/\G([,()]|[^,()]+)/g) {
  my $token = ;
  if ($token eq ',' and !$nesting) {
    push @vals, $buffer;
    $buffer = '';
  } else {
    $buffer .= $token;
    if ($token eq '(') {
      $nesting++;
    } elsif ($token eq ')') {
      $nesting--;
    }
  }
}
push @vals, $buffer if length $buffer;

print "$_\n" for @vals;

您可以使用Parser::MGC更抽象地构造这种解析器。