Как сбросить переменную $ 1 perl? - PullRequest
2 голосов
/ 16 марта 2020

Я пытаюсь сопоставить регулярные выражения:

$address =~ s/$re_region//;
$new_address_h->{ region     } =  $1  //'';

# $1 =  undef; # ERROR: Modification of a read-only value attempted at ...
$address =~ s/$re_city//;
$new_address_h->{ city       } =  $1;

Когда город не соответствует, я хочу, чтобы он был заполнен undef. Но когда city не совпадает, $1 имеет значение из предыдущего совпадения. Почему? Я ожидаю, что при сбое сопоставления его вывод не имеет значений, даже специальных переменных. как eval сбрасывает $@

Возможно ли это без дополнительных if s?

Ответы [ 2 ]

7 голосов
/ 16 марта 2020

Это задокументированное поведение ( 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/;
1 голос
/ 17 марта 2020

Наконец я использую троичный оператор без do:

$new_address_h->{ region } =  $address =~ s/$re_region//?
    $1 : '';

$new_address_h->{ city   } =  $address =~ s/$re_city//?
    $1 : undef;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...