Это задокументированное поведение ( perlvar ):
Perl устанавливает эти переменные в случае успешного совпадения, поэтому вы должны проверить результат сопоставления перед их использованием.
Вы можете использовать do с троичным оператором для заполнения ha sh:
$new_address_h->{region} = do { $address =~ s/$re_region// ? $1 : undef };
$new_address_h->{city} = do { $address =~ s/$re_city// ? $1 : undef };
В качестве альтернативы, заполните ha sh undefs и затем замените их значениями, если есть совпадение:
my $new_address_h = { region => undef, city => undef };
$address =~ s/$re_region// and $new_address_h->{region} = $1;
$address =~ s/$re_city// and $new_address_h->{city} = $1;
Обычный способ - просто сопоставить, а не заменить и заполнить в списке назначения:
($new_address_h->{region}) = $address =~ /$re_region/;
($new_address_h->{city}) = $address =~ /$re_city/;