我有一个用逗号分隔的字符串,我想匹配每个不在括号中的逗号(保证括号是平衡的)。
a , (b) , (d$_,c) , ((,),d,(,))
a和(b),(b)和(d $ ,c),(d $ ,c)和((,),d,(,))之间的逗号应匹配但不在(d $ _,c)或((,),d,(,))内部。
注意:最终,我想用这些逗号分割字符串。
它尝试了此正则表达式:
here中的(?!<(?:\(|\[)[^)\]]+),(?![^(\[]+(?:\)|\]))
,但仅适用于非嵌套括号。
答案 0 :(得分:4)
您可以使用
(\((?:[^()]++|(?1))*\))(*SKIP)(*F)|,
请参见regex demo
详细信息
(\((?:[^()]++|(?1))*\))
-捕获组1:匹配平衡括号之间的子字符串:
\(
-一个(
字符(?:[^()]++|(?1))*
-除(
和)
或整个第1组模式(由于regex subroutine (?1)
之外,出现零个或多个出现1+个字符这是必需的,因为仅递归整个正则表达式模式的一部分)\)
-一个)
字符。(*SKIP)(*F)
-忽略找到的匹配项,并从匹配项结尾开始下一个搜索|
-或,
-与嵌套括号外的逗号匹配。答案 1 :(得分:1)
单个正则表达式非常复杂,难以维护或扩展。这是一种迭代解析器方法:
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 = $1;
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更抽象地构造这种解析器。