sub preserve_case { my ($to, $from) = @_; die "strings don't match in length" unless length($to) == length($from); my $mask = join '', map /\w/ ? $_ & ' ' : "\0", split //, $from; return uc($to) | $mask; }