我正在使用一个大型数据集,基本上归结为这样的东西:
my $input = q(
<foo>111</foo>
<foo>222</foo>
<foo>333</foo>
<foo></foo>
<foo>555</foo>
); # new-lines are either CR+LF, LF, or CR
基于上面的例子,我们假设以下约束有效:
<foo>...</foo>
。foo
)来包含其数据。最终,以上面的数据来源为例,我想最终得到类似的东西:
my %values = (
one => '111',
two => '222',
three => '333',
four => '',
five => '555'
);
这是我的尝试:
my @vals = $input =~ m!<foo>(.*?)</foo>!ig;
if (scalar @vals != 5) {
# panic
}
my %values = (
one => shift @vals,
two => shift @vals,
three => shift @vals,
four => shift @vals,
five => shift @vals
);
这是我想要的,但它看起来很丑,并不是很灵活。不幸的是,这是我现在能做的最好的事情,因为我是Perl的新手。
所以,鉴于上述限制,有什么更优雅的方法呢?
答案 0 :(得分:4)
将两个数组合并为一个哈希:
my @keys = qw/one two three/;
my @values = qw/alpha beta gamma/;
my %hash;
@hash{@keys} = @values;
答案 1 :(得分:3)
首先,再看看:
my %values = (
one => '111',
two => '222',
three => '333',
four => '',
five => '555'
);
此数据结构将整数与一段数据相关联。但是已经存在一个内置数据结构,它具有相同的用途:Arrays。
所以,使用数组。您可以编写$values{ one }
而不是编写$values[ 0 ]
,而整数和数据值之间的映射将是透明的。
如果键不是整数,则可以执行以下操作:
use strict; use warnings;
my @keys = qw(a b c d e);
my $input = q(
<foo>111</foo>
<foo>222</foo>
<foo>333</foo>
<foo></foo>
<foo>555</foo>
); # new-lines are either CR+LF, LF, or CR
my %values;
# hash slice
@values{ @keys } = $input =~ m{ <foo> (.*?) </foo>}gix;
use YAML;
print Dump \%values;
输出:
--- a: 111 b: 222 c: 333 d: '' e: 555
答案 2 :(得分:2)
哦,这样的东西可以给予还是带走?
use Number::Spell;
$input =~ s|<(?:/)?foo>||g;
my @lines = grep { $_ } split "\n", $input; # grep for blank lines
my $i = 0;
my %hash = map { spell_number($i++) => $_ } @lines;
嗯,我可以做得更好。
use Number::Spell;
my $i = 0;
my %hash = map { s|<(?:/)?foo>||g; $_ ? spell_number($i++) => $_ : () }
split "\n", $input;
<强>编即可。哎呀,有一个@lines而不是$ input inna第二个片段。 谨慎使用;我只输入了这段代码;我还没有写过单元测试。