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?
In Perl, there's generally more than one way to do it, and as your problem involves parsing, one solution is, of course, regexes:
my $text = "width=13\nheight=15\nname=Mirek";
$text ~~ / [(\w+) \= (\N+)]+ %% \n+ /;
my %params = $0>>.Str Z=> $1>>.Str;
Another useful tool for data extraction is comb()
, which yields the following one-liner:
my %params = $text.comb(/\w+\=\N+/)>>.split("=").flat;
You can also write your original approach that way:
my %params = $text.split("\n")>>.split("=").flat;
or even simpler:
my %params = $text.lines>>.split("=").flat;
In fact, I'd probably go with that one as long as your data format does not become any more complex.
If you have more complex data format, you can use 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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With