my $xpm = qq{
:/* XPM */
:static char *xpm[] = $lb
:"$w $h $nsyms 1",
};
# Fill in XPM color symbols
foreach my $key (keys %$h_xpm) {
my $line = sprintf "%s c %s", $key, $h_xpm->{$key};
$xpm .= qq{\n\t\t:"$line",};
}
$xpm =~ s/(^\s+:)|((?<=\n)\s+:)|(\s+$)//g;
Why add the leading whitespace and colon when you are just going to remove them anyway?
And the substitution would be more efficient as:
$xpm =~ s/^\s+://mg;
$xpm =~ s/\s+$//;
Or at least don't use unneeded capturing parentheses:
$xpm =~ s/(?:^\s+:)|(?:(?<=\n)\s+:)|(?:\s+$)//g;