Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

parse string with pairs of values into hash the Perl6 way

Tags:

raku

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?

like image 889
user983447 Avatar asked Feb 07 '15 20:02

user983447


2 Answers

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.

like image 69
Christoph Avatar answered Sep 20 '22 10:09

Christoph


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;
like image 33
wamba Avatar answered Sep 22 '22 10:09

wamba