На что действует оператор подстановки Perl?

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

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

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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
13
0
3 410
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Хммм ... ($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»

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

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

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

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

Это правильный ответ. Я набирал это, когда это было опубликовано. Это (решение), кстати, заняло у меня один поиск в Google, чтобы найти.

Paul 07.12.2008 05:15

@ Д.Шоули. Jees mate. Из того, что вы сказали выше, почему нужно изменить $ _? «скопируйте строку из $ a ($ _) ... в $ b ($ lotr) и измените $ b ($ lotr) с помощью регулярного выражения, поместите результат в $ b ($ lotr)». Никакого волшебства, связанного с $ _.

Rob Wells 07.12.2008 05:34

Спасибо, мистер Шоули. Я много использую IDL, а в IDL нет операторов на месте - все равно $ y = f ($ x). Эта грамматика превратилась в умственную привычку, которая мешала мне грокнуть элементарный Perl. Спасибо за разлочку.

Ed Hyer 07.12.2008 20:22

@Rob - хе-хе-хе ... почему-то я всегда ожидаю, что Perl проскальзывает в $_, когда вы не смотрите;)

D.Shawley 09.12.2008 04:00

Разные языки делают разные вещи с оператором присваивания. В некоторых случаях это утверждение, а не выражение, поэтому его нельзя объединить в более крупное выражение. В некоторых случаях он возвращает присвоенное значение, но только как значение (часто называемое 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.

Спасибо, хорошо знать, что синтаксис примера, хотя и не волшебный, специфичен для Perl.

Ed Hyer 09.12.2008 21:21

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

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

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

Другие вопросы по теме