我有一个表达式,我需要拆分并存储在数组中:
aaa="bbb{ccc}ddd" { aa="bb,cc" { a="b", c="d" } }, aaa="bbb{}" { aa="b}b" }, aaa="bbb,ccc"
一旦拆分并存储在数组中,它应该看起来像这样:
aaa="bbb{ccc}ddd" { aa="bb,cc" { a="b", c="d" } }
aaa="bbb{}" { aa="b}b" }
aaa="bbb,ccc"
我使用的是Perl版本5.8,有人可以解决这个问题吗?
答案 0 :(得分:9)
使用perl模块“Regexp :: Common”。它有一个很好的平衡括号正则表达式,效果很好。
# ASN.1
use Regexp::Common;
$bp = $RE{balanced}{-parens=>'{}'};
@genes = $l =~ /($bp)/g;
答案 1 :(得分:6)
perlre中有一个示例,使用v5.10中引入的递归正则表达式功能。虽然你受限于v5.8,但是其他人也会得到正确的解决方案:)
$re = qr{
( # paren group 1 (full function)
foo
( # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> [^()]+ ) # Non-parens without backtracking
|
(?2) # Recurse to start of paren group 2
)*
)
\)
)
)
}x;
答案 2 :(得分:1)
尝试这样的事情:
use strict;
use warnings;
use Data::Dumper;
my $exp=<<END;
aaa="bbb{ccc}ddd" { aa="bb,cc" { a="b", c="d" } } , aaa="bbb{}" { aa="b}b" }, aaa="bbb,ccc"
END
chomp $exp;
my @arr = map { $_ =~ s/^\s*//; $_ =~ s/\s* $//; "$_}"} split('}\s*,',$exp);
print Dumper(\@arr);
答案 3 :(得分:1)
我或多或少同意Scott Rippey编写自己的解析器。这是一个简单的:
my $in = 'aaa="bbb{ccc}ddd" { aa="bb,cc" { a="b", c="d" } }, ' .
'aaa="bbb{}" { aa="b}b" }, ' .
'aaa="bbb,ccc"'
;
my @out = ('');
my $nesting = 0;
while($in !~ m/\G$/cg)
{
if($nesting == 0 && $in =~ m/\G,\s*/cg)
{
push @out, '';
next;
}
if($in =~ m/\G(\{+)/cg)
{ $nesting += length $1; }
elsif($in =~ m/\G(\}+)/cg)
{
$nesting -= length $1;
die if $nesting < 0;
}
elsif($in =~ m/\G((?:[^{}"]|"[^"]*")+)/cg)
{ }
else
{ die; }
$out[-1] .= $1;
}
(在Perl 5.10中测试过;对不起,我没有Perl 5.8,但据我所知,没有任何相关的差异。)不用说,你会想要替换{{1}用特定于应用程序的东西。而且您可能需要调整上述内容来处理示例中未包含的案例。 (例如,引用的字符串可以包含die
吗?可以使用\"
代替'
吗?此代码无法处理这两种可能性。)
答案 4 :(得分:1)
要匹配平衡括号或大括号,并且如果您想考虑反斜杠(转义),则建议的解决方案将不起作用。相反,您可以编写如下内容(以 perlre 中建议的解决方案为基础):
$re = qr/
( # paren group 1 (full function)
foo
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
/x;
答案 5 :(得分:0)
虽然Recursive Regular Expressions通常可用于捕获“平衡括号”{}
,但它们不适合您,因为您还需要匹配“平衡引号”"
。
对于Perl正则表达式来说,这将是一项非常棘手的任务,我相当肯定这是不可能的。 (相反,它可以用Microsoft's "balancing groups" Regex feature)完成。
我建议您创建自己的解析器。在处理每个字符时,您会计算每个字符"
和{}
,并且如果它们是“平衡的”,则只会在,
上拆分。
答案 6 :(得分:-1)
拆分解决方案似乎最简单。在主要变量aaa
的前瞻中拆分,并使用单词边界。使用可选字符组删除尾随空格和逗号。
$string = 'aaa="bbb{ccc}ddd" { aa="bb,cc" { a="b", c="d" } }, aaa="bbb{}" { aa="b}b" }, aaa="bbb,ccc"';
my @array = split /[,\s]*(?=\baaa\b)/, $string;