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



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

#!/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}
例如,每个奇数行都

包含一个唯一的"名称",每个偶数行都包含多个"键值"对 - 空格分隔。

  • 键始终是一个单词 (\w+)
  • 该值可以是:
    • 一个字符串 (\S+),或
    • 多个空格分隔的字符串,用方括号 { } 括起来

需要将上述文件放入perl结构中,或者:

$ALL => {
    name1 => {
        key1 => ["val1"],
        key2 => ["val2a", "val2b"],
        key3 => ["val3"]
    },
[.......]

$ALL => {
    name1 => {
        key1 => {
           val1 => undef,
        },
        key2 => {
           val2a => undef,
           val2b => undef,
        }
        key3 => {
           val3 => undef,
        }
    },
[.......]

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

需要一些提示,如何在上面的 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}

这似乎会产生您正在寻找的输出(选项 1)。

最新更新