use strict;
use warnings;
use Data::Dumper;
my $contents = qq(
create item "xxx" {
remove entry "}x{"
add entry "yy" "xxx" {
item1=xxxx,
item2=xxxx,
}
add diffenent entry "}}xxx" {
item1=xxx,
item2=xxxx,
item3=xxx
add subitem {
item1=xxx,
item2=xxx,
item3=xxx
}
add subitem {
item1=xxx,
item2=xxx,
}
}
another type {
item1=xxx
} with "{{xxx"
}
);
(my $re=$contents)=~s/(({)|(})|"(\\.|[^"\\])*"|.)/@{[')','']}[!$3]\Q$1
+\E@{['(','']}[!$2]/gs;
print Dumper(@$=eval{$contents=~/$re/});
die $@ if $@;
$re=join"|",map{"\Q$_\E"}@$;
print Dumper extract($contents);
sub extract{
my $c=shift;
my @r;
while( $c =~ /(\S.*?)\s*(?:{($re)} *(.*)|$)/mg ){
my($h,$b,$t)=($1,$2,$3);
push @r,$b?[$h,extract($b),$t||()]:$h;
}
return @r?[@r]:$c;
}