use strict; use warnings; use Data::Dumper; my $data = str2data('foo[1].bar.baz[0]', 123); print Dumper($data), "\n"; sub str2data { my($string, $value) = @_; my $r = \my $return; $r = $1 ? \$$r->{$1} : \$$r->[$2] while $string =~ /\G(?:\.?(\w+)|\[(\d+)\])/g; $$r = $value; $return; }