Я страдал от головной боли, ища это: Как Вы используете s///в выражении в противоположность присвоению. Для разъяснения, что я имею в виду я ищу жемчуг, эквивалентный из re.sub Python (...) при использовании в следующем контексте:
newstring = re.sub('ab', 'cd', oldstring)
Единственным путем я знаю, как сделать, это в жемчуге до сих пор:
$oldstring =~ s/ab/cd/;
$newstring = $oldstring;
Отметьте дополнительное присвоение.
Похоже, вы неправильно понимаете, как работает = ~
. = ~
- это оператор привязки, который связывает переменную с оператором регулярного выражения. Он не выполняет никаких заданий.
Все операторы регулярного выражения по умолчанию работают с переменной темы $ _
, поэтому s / foo / bar /;
совпадает с $ _ = ~ s / foo / bar /;
. Присваивания не происходит. Переменная темы преобразована.
Случай аналогичен при работе с любой другой переменной. $ var = ~ s / foo / bar /;
преобразует $ var
, заменяя первый экземпляр foo
на bar
. Присваивания не происходит.
Лучший совет, который я могу вам дать, - писать Python на Python и Perl на Perl. Не ожидайте, что эти два языка будут одинаковыми.
Вы могли бы поступить так, как предлагает DVK, и написать подпрограмму, которая будет воспроизводить поведение замены, к которому вы привыкли.
Или вы можете попробовать какой-нибудь идиоматический Perl. Основываясь на вашем выраженном желании применить несколько преобразований в одной строке, я привел пару примеров, которые могут оказаться полезными.
Здесь я использую цикл for
над одним элементом, чтобы актуализировать $ var
и применить множество жестко запрограммированных преобразований:
for( $var ) {
s/foo/bar/;
s/fizz/buzz/;
s/whop/bop-a-loo-bop/;
s/parkay/butter/;
s/cow/burger/;
}
Или, может быть, вам нужно применить переменную группу преобразований . Я определяю подпрограмму для перебора списка ссылок на массивы, которые определяют старые / новые пары преобразований. В этом примере используется обработка аргументов Perl, ориентированная на список, для обработки любого количества преобразований.
my $foo = transform(
'abcd' =>
[ 'a', 'b' ],
[ 'bb', 'c' ],
[ 'cc', 'd' ],
[ 'dd', 'DONE' ],
);
sub transform {
my $var = shift;
for (@_ ) {
my ($old, $new) = @$_;
$var =~ s/$old/$new/;
}
return $var;
}
И, наконец, немного возиться с предоставлением версии преобразования, изменяющей его первый аргумент:
my $foo = 'abcd';
transform_in_place(
$foo =>
[ 'a', 'b' ],
[ 'bb', 'c' ],
[ 'cc', 'd' ],
[ 'dd', 'DONE' ],
);
print "$foo\n";
sub transform_in_place {
for my $i (1..$#_ ) {
my ($old, $new) = @{$_[$i]};
$_[0] =~ s/$old/$new/;
}
}
Для моего собственного проекта я, вероятно, использовал бы один из первых двух вариантов в зависимости от потребностей конкретной проблемы.
Подстановка регулярных выражений Perl всегда выполняется "на месте". Поэтому вам нужно скопировать строку в новую переменную и работать с новой переменной:
(my $newstring = $oldstring) =~ s/ab/cd/;
Вы можете использовать ($ new = $ old) = ~ s / something / whateverelse /;
для точно такой же функциональности, которую вы ищете:
use strict;
my $old = "OLD";
my $new;
($new = $old) =~ s/OLD/NEW/;
print "old=$old, new=$new";
Производит:
old=OLD, new=NEW
Именно то, что вы хотите
Если вы ищете функцию, вы можете просто определить ваше собственное, чтобы избежать присваивания:
use strict;
sub re_sub {
my ($find, $replace, $old) = @_;
my $new = $old;
$new =~ s/$find/$replace/;
return $new;
}
my $old = "ab";
my $new = re_sub('ab', 'cd', $old);
print "new=$new\n";
Результаты в new = cd
.
Основываясь на этом, правильно ли я предполагаю, что вы не можете иметь два s /// в одной строке, одна из которых использует результат другой, без промежуточных присваиваний? - mikeY
Да, вы правы. Если вы хотите применить несколько замен к одной и той же строке, я бы сделал
$newstring = $oldstring ;
$newstring =~ s/ab/cd/ ;
$newstring =~ s/xx/yy/ ;
Следующее не сработает, потому что s //
возвращает количество сделанных замен, а не измененная строка.
$newstring = $oldstring) =~ s/ab/cd/ =~ s/xx/yy/ ;
Таким образом, операции регулярных выражений Perl сильно отличаются от операций Python, и вам лучше попытаться изучить, что Perl делает с нуля, а не пытаться сопоставить концепции Python с Perl
Вы хотите, чтобы результатом подстановки была $ newstring, верно?
Примерно так:
($newstring = $oldstring) =~ s/ab/cd;
Должно сработать. Присваивание устанавливает $ newstring
в $ oldstring
, а затем вычисляет значение $ newstring
, на которое действует подстановка.