Expand hostnames from a string of hostnames and/or regex
Your function expects a single argument that should contain hostnames or patterns separated by spaces:

sub expand_names {
    my $host = shift;
    my @raw_hosts = split(' ', $host);
    foreach my $raw_name (@raw_hosts) {


Why not use multiple arguments?

sub expand_names {
    foreach my $raw_name (@_) {


Since @hosts is empty when you reach this code:

# Gather all the hosts we found
foreach $raw_name  (keys %host_hash) {
    @hosts = (@hosts, (keys %{$host_hash{$raw_name}}));
}


You could simplify:

foreach $raw_name  (keys %host_hash) {
    push(@hosts, keys %{$host_hash{$raw_name}});
}


And actually, I don't see the reason for building a map of maps, when a simple flat map will do.
Consider this alternative implementation:

sub expand_names {
    my %hosts;
    foreach my $raw_name (@_) {
        #if the name might contain regex, let's see what it matched
        if ($raw_name !~ m/^[a-zA-Z0-9-]+$/) {
            my $found = 0;
            foreach my $target (@target_list) {
                if ($target =~ m/^$raw_name$/) {
                    $found = $hosts{$target} = 1;
                }
            }
            $hosts{$raw_name} = 1 if not $found;
        } else {
            # Regular host name or dotted-decimal
            $hosts{$raw_name} = 1;
        }
    }
    return sort keys %hosts;
}