На что действует оператор подстановки Perl? - PullRequest
13 голосов
/ 07 декабря 2008

Я программирую на Perl время от времени, но только время от времени это мой основной язык. Поскольку я часто провожу месяцы без написания Perl, я сильно полагаюсь на свою книгу с верблюжьими ушами, чтобы напомнить мне, как делать вещи. Однако, когда я копирую рецепты дословно без понимания, это беспокоит меня. Это один из самых неприятных: на странице 154 3-го издания Camel приведен пример «модификации строк en passant », который выглядит следующим образом:

($lotr = $hobbit) =~ s/Bilbo/Frodo/g;

Q1) что здесь происходит? На чем конкретно работает регулярное выражение?

Q2) Необходим ли этот почти магический синтаксис для такой базовой операции, как «взять строку из $ a, изменить ее с помощью регулярного выражения, поместить результат в $ b»?

Q3) Как мне сделать эту операцию, используя переменную цикла по умолчанию в качестве начальной строки?

Заранее извиняюсь перед мечтателями Perl, для которых все вышесказанное выглядит совершенно естественным.

Ответы [ 3 ]

22 голосов
/ 07 декабря 2008

Хммм ... ($lotr=$hobbit) =~ s/Bilbo/Frodo/g - одна из многих магий Perl. Теперь о некоторых ответах.

Q1) $lotr присваивается значение, содержащееся в $hobbit. После присваивания мы можем забыть об исходной переменной. Относитесь к ($lotr = $hobbit) как к собственному утверждению, как если бы мы написали:

$lotr = $hobbit;
$lotr =~ s/Bilbo/Frodo/g;

вместо этого. Регулярное выражение работает на $lotr.

Q2) Синтаксис представляет собой однострочную версию фрагмента, приведенного выше. Думайте об этом как "скопируйте строку из $a, скопируйте ее в $b и измените $b с помощью регулярного выражения" вместо "взять строку из $a, измените ее с помощью регулярного выражения, поместите результат в $b "

В3) Я предполагаю, что вы имеете в виду пространство поиска шаблона по умолчанию под "петлей переменной по умолчанию"? В этом случае просто используйте $_ вместо $hobbit:

while (<>) {
  chomp;
  ($lotr = $_) =~ s/Bilbo/Frodo/g;
  print "\$lotr = [$lotr]\n";
  print "\$_    = [$_]\n";
}

Интересно, что магическая переменная $_ не модифицируется этой операцией. Таким образом, вы можете сделать вывод, что присваивание происходит за до подстановки регулярного выражения и что подстановка никак не взаимодействует с пространством шаблона по умолчанию.

А что касается опытных программистов на Perl ... Я не знаю слишком многих людей, которых выбрасывает какой-то фрагмент синтаксиса Perl, независимо от того, как долго они на это смотрят, за исключением, конечно, мистера Шварца;)

5 голосов
/ 07 декабря 2008

Разные языки делают разные вещи с оператором присваивания. В некоторых это утверждение, а не выражение, поэтому его нельзя объединить в большее выражение. В некоторых он возвращает назначенное значение, но только как значение (часто называемое rvalue), а не как нечто, что само может быть изменено или назначено (lvalue). Примером этого является C, где вы можно написать:

 a = b = c;  # assign value of c to b and a

но не:

 ++(b = a);  # assign value of a to b, then increment b

И в некоторых случаях результатом присваивания является присвоенное значение lvalue. (В Perl это относится только к скалярным назначениям; список назначений - более сложный зверь.) Так что вы можете сделать ++ ($ b = $ a) или ($ b = $ a) = ~ s / a / b / любая другая операция, которая ожидает lvalue в назначении, и она сначала выполнит назначение, а затем дополнительно изменит lvalue, назначенный для.

1 голос
/ 07 декабря 2008

Если в Q2 вы хотите взять подстроку из $ a, вам может пригодиться эта идиома:

($b) = $a =~ /(substring-to-match)/;
$b =~ s/regex-on-susbtring/result-string/;

Также обратите внимание, что $ a и $ b не являются обычными переменными в Perl, поскольку у них есть специальные правила области видимости, связанные с функцией сортировки. Смотрите 'perldoc perlvar' для деталей.

...