6

I have a string which looks like that:

width=13
height=15
name=Mirek

I want to turn it into hash (using Perl 6). Now I do it like that:

my $text = "width=13\nheight=15\nname=Mirek";
my @lines = split("\n", $text);
my %params;
for @lines {
    (my $k, my $v) = split('=', $_);
    %params{$k} = $v;
}
say %params.perl;

But I feel there should exist more concise, more idiomatic way to do that. Is there any?

4

2 回答 2

9

在 Perl 中,通常有不止一种方法可以做到这一点,并且由于您的问题涉及解析,因此一种解决方案当然是正则表达式:

my $text = "width=13\nheight=15\nname=Mirek";
$text ~~ / [(\w+) \= (\N+)]+ %% \n+ /;
my %params = $0>>.Str Z=> $1>>.Str;

另一个用于数据提取的有用工具是comb(),它产生以下单行:

my %params = $text.comb(/\w+\=\N+/)>>.split("=").flat;

你也可以这样写你的原始方法:

my %params = $text.split("\n")>>.split("=").flat;

甚至更简单:

my %params = $text.lines>>.split("=").flat;

事实上,只要您的数据格式不会变得更复杂,我可能会使用那个。

于 2015-02-08T09:58:03.813 回答
2

如果你有更复杂的数据格式,你可以使用grammar.

grammar Conf {
    rule  TOP   { ^ <pair> + $ }
    rule  pair  {<key> '=' <value>}
    token key   { \w+ }
    token value { \N+ }
    token ws    { \s* }
}

class ConfAct {
    method TOP   ($/) { make (%).push: $/.<pair>».made}
    method pair  ($/) { make $/.<key>.made => $/.<value>.made }
    method key   ($/) { make $/.lc }
    method value ($/) { make $/.trim }
}

my $text = " width=13\n\theight = 15 \n\n nAme=Mirek";
dd Conf.parse($text, actions => ConfAct.new).made;
于 2017-10-03T11:27:03.410 回答