Расширение переменных во входных данных  
Проблема
Имеется строка, внутри которой присутствует ссылка на переменную: You owe $debt to me.
Требуется заменить имя переменной $debt в строке ее текущим значением.
Решение
Если все переменные являются глобальными, воспользуйтесь подстановкой с символическими ссылками:
$text =~ s/\$(\w+)/${$1}/g;
Но если среди переменных могут встречаться лексические (
mу) переменные, следует использовать /ее:
$text =~ s/(\$\w+)/$1/gee;
 
Комментарий
Первый способ фактически сводится к следующему: мы ищем нечто похожее на имя переменной, а затем 
интерполируем ее значение посредством символического разыменования (dereferencing). Если $1 содержит 
строку somevar, то ${$1} будет равно содержимому $somevar. Такой вариант не будет работать при 
действующей директиве use strict 'refs', 
потому что она запрещает символическое разыменование.
Приведем пример:
use vars qw($rows $cols);
no strict 'refs';          # для приведенного ниже ${$1}
my $text;
($rows, $cols) = (24, 80);
$text = q(I am $rows high and $cols long);  # апострофы!
$text =~ s/\$(\w+)/${$1}/g;
print $text;
1 am 24 high and 80 long
Возможно, вам уже приходилось видеть, как модификатор подстановки /е используется для вычисления 
заменяющего выражения, а не строки. Допустим, вам потребовалось удвоить каждое целое число в строке:
$text = "I am 17 years old";
$text =~ s/(\d+)/2 * $1/eg;
 
Перед запуском программы, встречая /е при подстановке, Perl компилирует код заменяющего выражения вместе с 
остальной программой, задолго до фактической подстановки. При выполнении подстановки $1 заменяется 
найденной строкой. В нашем примере будет вычислено следующее выражение:
2 * 17
 
Но если попытаться выполнить следующий фрагмент:
$text = 'I am $AGE years old';  # Обратите внимание на апострофы!
$text =~ s/(\$\w+)/$1/eg;       # НЕВЕРНО
 
при условии, что $text содержит имя переменной $AGE, Perl послушно заменит $1 на $AGE и вычислит следующее выражение:
'$AGE'
 
В результате мы возвращаемся к исходной строке. Чтобы получить значение переменной, необходимо снова 
вычислить результат. Для этого в строку добавляется еще один модификатор /е:
$text =~ s/(\$\w+)/$1/eeg;    # Находит переменные mу()
 
Да, количество модификаторов /е может быть любым. Только первый модификатор компилируется вместе с 
программой и проверяется на правильность синтаксиса. В результате он работает аналогично конструкции 
eval {BLOCK}, хотя и не перехватывает исключений. Возможно, лучше провести аналогию с 
do {BLOCK}.
Остальные модификаторы /е ведут себя иначе и больше напоминают конструкцию 
eval "STRING". Они не 
компилируются до выполнения программы. Маленькое преимущество этой схемы заключается в том, что вам 
не придется вставлять в блок директиву no strict 'refs'. Есть и другое огромное преимущество: 
этот механизм позволяет находить лексические переменные, созданные с помощью ту, — символическое 
разыменование на это не способно.
В следующем примере модификатор /х разрешает пропуски и комментарии в шаблоне подстановки, а 
модификатор /е вычисляет правостороннее выражение на программном уровне. Модификатор /е позволяет 
лучше управлять обработкой ошибок или других экстренных ситуаций:
# Расширить переменные в $text. Если переменная не определена,
# вставить сообщение об ошибке.
$text =~ s{
  \$                         # Найти знак доллара
  (\w+)                      # Найти "слово" и сохранить его в $1
}{
  no strict 'refs';
  if (defined $$1) {
    $$1;                 # Расширять только глобальные переменные
  } else {
      "[NO VARIABLE: \$$1]"; # Сообщение об ошибке
    }
}egx;
Обратите внимание на изменение синтаксиса $$1 в Perl 5.004; когда-то это выражение означало ${$}1, а 
теперь оно означает ${$1}. Для обеспечения обратной совместимости в строках оно сохраняет старый смысл 
(но выдает предупреждение с -w). Запись ${$1} используется в строках для того, чтобы предотвратить разыменование PID. 
Если значение $$ равно 23448, то $$1 в строке превращается в 234481, а не в значение переменной, имя которой хранится в $1.
См. такжеОписание оператора 
s/// и функции 
eval 
 
 
  Proverte kod v komentariyah gde pro list tam oshibki detskie
  
  
 
Оставить комментарий:
 |   
 |