Главная страница


ru.perl

 
 - RU.PERL ----------------------------------------------------------------------
 From : Erelen Laiquendi                     2:5020/400     07 Apr 2004  15:48:51
 To : Vegn Irfunt
 Subject : Re: Парсинг строк
 -------------------------------------------------------------------------------- 
 
 VI> Есть строка, введённая с клавиатуры(файла). Hапример 'blabla bla
 VI> $a hello @array'
 VI> Требуется сделать сабж, так чтобы все переменные были заменены
 VI> соответствующими значениями.
 
 Perl Cookbook
 
 1.8. Расширение переменных во входных данных
 
 *** Проблема ***
 
 Имеется строка, внутри которой присутствует ссылка на переменную:
 
 You owe $debt to me.
 
 Требуется заменить имя переменной $debt в строке её текущим значением.
 
 *** Решение ***
 
 Если все переменные являются глобальными, воспользуйтесь подстановкой
 с символическими ссылками:
 
 $text =~s/\$(\w+)/${$1}/g;
 
 Hо если среди переменных могут встречаться лексические (mу)
 переменные, следует использовать /её:
 
 $text =~ s/(\$\w+)/$1/gee;
 
 *** Комментарий ***
 
 Первый способ фактически сводится к следующему: мы ищем нечто похожее
 на имя переменной, а затем интерполируем её значение посредством
 символического разыменования (dereferencing). Если $"( содержит строку
 somevar, то ${$1} будет равно содержимому $somevar. Такой вариант не
 будет работать при действующей директиве use st rict ' rets , потому
 что она запрещает символическое разыменование. Приведём пример:
 
 use vars qw($rows $cols);
 no strict 'rets'; # для приведённого ниже ${$1} my $text;
 ($rows, $cols) = (,^, 80):
 $text = q(i am $ rows high and $cols long); # апострофы! $text =~
 s/\$(\w+)/${$1}/g;
 print $text;
 
 I am 24 high and 80 long
 
 Возможно, вам уже приходилось видеть, как модификатор подстановки /е
 используется для вычисления заменяющего выражения, а не строки.
 Допустим, вам потребовалось удвоить каждое целое число в строке:
 
 $text = "i am 17 years old";
 $text ="" s/(\d+)/2 * $1/eg;
 
 Перед запуском программы, встречая /е при подстановке, Perl
 компилирует код заменяющего выражения вместе с остальной программой,
 задолго до фактической подстановки. При выполнении подстановки $1
 заменяется найденной строкой. В нашем примере будет вычислено
 следующее выражение:
 
 2 * 17
 
 Hо если попытаться выполнить следующий фрагмент:
 
 $text = 'i am $age years old'; # Обратите внимание на апострофы!
 $text =~ s/(\$\w+)/$1/eg; # HЕВЕРHО
 
 при условии, что $text содержит имя переменной $AGE, Perl послушно
 заменит $1 на $AGE и вычислит следующее выражение:
 
 '$AGE'
 
 В результате мы возвращаемся к исходной строке. Чтобы получить
 значение переменной, необходимо снова вычислить результат. Для этого в
 строку добавляется ещё один модификатор /e:
 
 $text =~ s/(\$\w+)/$1/eeg; # Hаходит переменные mу()
 
 Да, количество модификаторов /е может быть любым. Только первый
 модификатор компилируется вместе с программой и проверяется на
 правильность синтаксиса. В результате он работает аналогично
 конструкции eval {BLOCK}, хотя и не перехватывает исключений.
 Возможно, лучше провести аналогию с do {BLOCK}.
 
 Остальные модификатора! /е ведут себя иначе и больше напоминают
 конструкцию eval "STRING". Они не компилируются до выполнения
 программы. Маленькое преимущество этой схемы заключается в том, что
 вам не придётся вставлять в блок директиву no strict 'refs'. Есть и
 другое огромное преимущество: этот механизм позволяет находить
 лексические переменные, созданные с помощью my, - символическое
 разыменование на это не способно.
 
 В следующем примере модификатор /х разрешает пропуски и комментарии в
 шаблоне подстановки, а модификатор /е вычисляет правостороннее
 выражение на программном уровне. Модификатор /е позволяет лучше
 управлять обработкой ошибок или других экстренных ситуаций:
 
 # Расширить переменные в $text. Если переменная не определена,
 # вставить сообщение об ошибке.
 $text =~ s{
   \$                         # Hайти знак доллара
   (\w+)                      # Hайти "слово" и сохранить его в $1
 }{
   no strict 'refs';
   if (defined $$1) {
     $$1;                     # Расширять только глобальные переменные
   } else {
     "[NO VARIABLE: \$$1];    # Сообщение об ошибке
 } }еgх;
 
 Обратите внимание на изменение синтаксиса $$1 в Perl 5.004; когда-то
 это выражение означало ${$}!, а теперь оно означает ${$1}. Для
 обеспечения обратной совместимости в строках оно сохраняет старый
 смысл (но выдаёт предупреждение с -w). Запись ${$1} используется в
 строках для того, чтобы предотвратить разыменование PID. Если значение
 $$ равно 23448, то $$1 в строке превращается в 234481, а не в значение
 переменной, имя которой хранится в $1.
 
 -- 
 Erelen Laiquendi
 mailto:erelen@pereslavl.ru
 ICQ: 277178 / Jabber: erelen@jabber.ru
 Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru
 --- ifmail v.2.15dev5.3
  * Origin: Talk.Mail.Ru (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 Парсинг строк   Vegn Irfunt   07 Apr 2004 13:03:32 
 Re: Парсинг строк   Erelen Laiquendi   07 Apr 2004 15:48:51 
 Re: Паpсинг стpок   Sergey Bychkov   07 Apr 2004 15:04:54 
Архивное /ru.perl/67457f17704a.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional