use CGI; my $cgi = CGI->new( 'a.b.c=3&a.b.c=4&x.y=4' ); my $args = {}; my @names = $cgi->param; foreach my $name (@names) { my $p = $args; my @keys = split /\./, $name; for my $i (0 .. $#keys-1) { $p = $p->{$keys[$i]} ||= {}; } my @values = $cgi->param($name); $p->{$keys[-1]} = @values==1 ? $values[0] : \@values; } use Data::Dumper; $Data::Dumper::Indent = 1; print Dumper $args;