将带有值对的字符串解析为 Perl6 方式的散列

parse string with pairs of values into hash the Perl6 way

我有一个看起来像这样的字符串:

width=13
height=15
name=Mirek

我想把它变成散列(使用 Perl 6)。现在我这样做了:

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;

但我觉得应该有更简洁、更惯用的方法来做到这一点。有没有?

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

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

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

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

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

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

或更简单:

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

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

如果你有更复杂的数据格式,你可以使用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;