in reply to Convert stirng to array of hashes

As moritz said, eval is the easiest way, but if you don't wish to take that risk:
use strict; use warnings; use Data::Dumper; my $string = q({file => 'file1', desc => 'test'}, {file => 'file12', +desc => 'test2'}); my @array_of_hashes; my @hashes = $string =~ /(\{.*?\})/g; for my $hashstr (@hashes) { my @keys = $hashstr =~ /(\w+)\s*=>/g; my @values = $hashstr =~ /=>\s*\'(\w+)\'/g; my %hash; @hash{@keys} = @values; push @array_of_hashes, \%hash; } print Dumper(\@array_of_hashes);
Gives:
$VAR1 = [ { 'desc' => 'test', 'file' => 'file1' }, { 'desc' => 'test2', 'file' => 'file12' } ];

Replies are listed 'Best First'.
Re^2: Convert stirng to array of hashes
by codeacrobat (Chaplain) on Aug 08, 2009 at 20:34 UTC
    You can also build a parser with TheDamian's Regexp::Grammars. Here is a proof of concept, which you can improve.
    use Regexp::Grammars; my $parser = qr{ (?: <[Hash]> ** ( , ) ) <token: Hash> \{ <[KV]> ** ( , ) \} <token: KV> (?: \s* <[Key]> \s* => \s* <[Value]> \s* ) <token: Key> \w* <token: Value> ' \w* ' }x; use Data::Dumper; # Match the grammar against some text... if ("{ foo => 'bar', baz => 'bof' }, {bing => 'go'}" =~ $parser) { # If successful, the hash %/ will have the hierarchy of results.. +. print Dumper(\%/ ); } __END__ $VAR1 = { '' => '{ foo => \'bar\', baz => \'bof\' }, {bing => \'go\'}' +, 'Hash' => [ { '' => '{ foo => \'bar\', baz => \'bof\' }', 'KV' => [ { '' => ' foo => \'bar\'', 'Value' => [ '\'bar\'' ], 'Key' => [ 'foo' ] }, { '' => 'baz => \'bof\' ', 'Value' => [ '\'bof\'' ], 'Key' => [ 'baz' ] } ] }, { '' => '{bing => \'go\'}', 'KV' => [ { '' => 'bing => \'go\'', 'Value' => [ '\'go\'' ], 'Key' => [ 'bing' ] } ] } ] };

    print+qq(\L@{[ref\&@]}@{['@'x7^'!#2/"!4']});
Re^2: Convert stirng to array of hashes
by Anonymous Monk on Aug 09, 2009 at 13:13 UTC
    thanks you Cdarke your code works .
    but i acctually i try to pass a variable to it. how should i correct it?

    many thanks

    use strict; use warnings; use Data::Dumper; my $str = "{file => 'file1', desc => 'test'}, {file => 'file12', desc + => 'test2'}" my $string = $str; my @array_of_hashes; my @array_of_hashes; my @hashes = $string =~ /(\{.*?\})/g; for my $hashstr (@hashes) { my @keys = $hashstr =~ /(\w+)\s*=>/g; my @values = $hashstr =~ /=>\s*\'(\w+)\'/g; my %hash; @hash{@keys} = @values; push @array_of_hashes, \%hash; } print "Pragma: no-cache\n"; print "Content-type:text/html\n\n"; print Dumper(\@array_of_hashes);




Re^2: Convert stirng to array of hashes
by courierb (Novice) on Aug 10, 2009 at 03:28 UTC
    Dear cdarke

    your code is indeed work . thank you very much .

    how ever i found when the value contain space or be empty
    value or even Japanese or Chinese fout. it will produce undef and
    eventually lead to mis match of key and value?



    for example: below case are non work



    desc => 'test no work'
    desc => ''
    desc => 'japanese_fond_here_non_work'


    Could you help me a a bit more this time?