in reply to nested loops and next

Use a label on your while loop:

HASH: while(my ($key, $value) = each %ids) { for my $item (@names) { if($item =~ m/$key/) { push @groups, $item; next HASH; } } }

Alternatively, you could also use last to exit the inner loop and let things take their natural course, as it were.