Perl 在一行中分析多个关键字-值对-混合分隔符-文本::平衡

Perl 在一行中分析多个关键字-值对-混合分隔符-文本::平衡,perl,Perl,具有以下文件结构-请参阅数据部分: #!/usr/bin/perl use strict; use warnings; use Text::Balanced qw(extract_bracketed); my($ALL, $name, $pairs); while(defined($name = <DATA>) && defined($pairs = <DATA>)) { $ALL->{$name} = parse_pairs($pai

具有以下文件结构-请参阅数据部分:

#!/usr/bin/perl  
use strict;
use warnings;
use Text::Balanced qw(extract_bracketed);

my($ALL, $name, $pairs);
while(defined($name = <DATA>) && defined($pairs = <DATA>)) {
    $ALL->{$name} = parse_pairs($pairs);
}

sub parse_pairs {
    my $str = shift;

    my($extracted, $remainder) = extract_bracketed($str,'{}'); # how to?


}    
__DATA__
name1
key1 val1 key2 {val2a val2b} key3 val3
name2
key2 val2 key3 val3
name3
key1 {val1a val1b val1c} key2 {val2a val2b}

这可能是文本::Ballanted的工作,但不知道如何使用它,因为这里有混合值,一些只是简单的单词,一些是Ballanted-括号括起来的,不知道如何重复提取;(


需要一些提示,如何在上面的src中编写
parse_pairs
sub。

以下是我所拥有的。它不是使用Text::Balanced,而是使用Regexp::Common:

#!/usr/bin/perl  
use strict;
use warnings;
use Regexp::Common;

my($ALL, $name, $pairs);
while(defined($name = <DATA>) && defined($pairs = <DATA>)) {
    chomp $name;
    chomp $pairs;
    $ALL->{$name} = parse_pairs($pairs);
}
use Data::Dump; dd $ALL;

sub parse_pairs {
    my $str = shift;

    my @key_values = $str =~ /
        (\w+)    # key
        \s*
        (\w+|$RE{balanced}{-parens=>'{}'}) # value
        \s*/xg;

    my $r;
    while (@key_values)
    {
        $key_values[1] =~ s/^\{//;
        $key_values[1] =~ s/\}$//;
        $r->{$key_values[0]} = [ split /\s+/, $key_values[1] ];
        splice @key_values, 0, 2;
    }
    $r;
}
__DATA__
name1
key1 val1 key2 {val2a val2b} key3 val3
name2
key2 val2 key3 val3
name3
key1 {val1a val1b val1c} key2 {val2a val2b}
!/usr/bin/perl
严格使用;
使用警告;
使用Regexp::Common;
我的($ALL,$name,$pairs);
while(已定义($name=)&&defined($pairs=)){
chomp$name;
咀嚼$pairs;
$ALL->{$name}=parse_pairs($pairs);
}
使用数据::Dump;dd$ALL;
子对{
我的$str=班次;
我的@key_值=$str=~/
(\w+)#键
\*
(\w+|$RE{balanced}{-parens=>'{}})#值
\s*/xg;
我的$r;
while(@key_值)
{
$key_values[1]=~s/^\{/;
$key\u values[1]=~s/\}$/;
$r->{$key_值[0]}=[split/\s+/,$key_值[1]];
拼接@key_值,0,2;
}
$r;
}
__资料__
名称1
key1 val1 key2{val2a val2b}key3 val3
姓名2
键2 val2键3 val3
名字3
键1{val1a val1b val1c}键2{val2a val2b}

这似乎产生了您想要的输出(选项1)。

非常感谢!这正是我想要的。太好了。;)现在需要稍微了解一下。)正则表达式扫描行中的键/值。对于值,它可以是\w+(一个“单词”)或大括号中的内容(如果不可能使用嵌套大括号,可能有一种更简单的方法)。一旦我们有了列表,奇数项是键,偶数项是值。如果该值的两端都有大括号,请将其删除。在空格上拆分(如果没有大括号,则没有空格,拆分不执行任何操作)。赋值以返回散列。剪接两个项目,循环下两个项目。
$ALL => {
    name1 => {
        key1 => {
           val1 => undef,
        },
        key2 => {
           val2a => undef,
           val2b => undef,
        }
        key3 => {
           val3 => undef,
        }
    },
[.......]
#!/usr/bin/perl  
use strict;
use warnings;
use Regexp::Common;

my($ALL, $name, $pairs);
while(defined($name = <DATA>) && defined($pairs = <DATA>)) {
    chomp $name;
    chomp $pairs;
    $ALL->{$name} = parse_pairs($pairs);
}
use Data::Dump; dd $ALL;

sub parse_pairs {
    my $str = shift;

    my @key_values = $str =~ /
        (\w+)    # key
        \s*
        (\w+|$RE{balanced}{-parens=>'{}'}) # value
        \s*/xg;

    my $r;
    while (@key_values)
    {
        $key_values[1] =~ s/^\{//;
        $key_values[1] =~ s/\}$//;
        $r->{$key_values[0]} = [ split /\s+/, $key_values[1] ];
        splice @key_values, 0, 2;
    }
    $r;
}
__DATA__
name1
key1 val1 key2 {val2a val2b} key3 val3
name2
key2 val2 key3 val3
name3
key1 {val1a val1b val1c} key2 {val2a val2b}