$keys = ''; $keys .= 'field' . 'A'; @keys = split /field/, $keys, -1; # grabs trailing zero-lengths pop @keys; #### use warnings; use strict; my @str = ( 'Value:', 'Value:.', 'Value:...', 'Value:A', 'Value:A.B', 'Value:.A', 'Value:A.', ); for (@str){ m/^ Value: \K (.*) $/x; my $keys = $1; my @keys; my $i = 0; @{ $keys[ $i ++ ] } = split /\./, $keys; @{ $keys[ $i ++ ] } = split /\./, $keys, -1; @{ $keys[ $i ++ ] } = $keys =~ m/\w*/g; @{ $keys[ $i ++ ] } = $keys =~ m/\w*?(?=\.|$)/g; my $keys_plus = $keys . '.A'; @{ $keys[ $i ++ ] } = split /\./, $keys_plus, -1; pop @{ $keys[ $i - 1 ] }; print "{$keys}:\n"; for my $j (0 .. $i - 1){ print map "<$_>\n", join '', map "[$_]", @{ $keys[ $j ] }; } print "\n"; } __END__ {}: <> <> <[]> <[]> <[]> {.}: <> <[][]> <[][]> <[][]> <[][]> {...}: <> <[][][][]> <[][][][]> <[][][][]> <[][][][]> {A}: <[A]> <[A]> <[A][]> <[A][]> <[A]> {A.B}: <[A][B]> <[A][B]> <[A][][B][]> <[A][][B][]> <[A][B]> {.A}: <[][A]> <[][A]> <[][A][]> <[][A][]> <[][A]> {A.}: <[A]> <[A][]> <[A][][]> <[A][][]> <[A][]>