Автор Тема: Регулярник для замены в шаблоне  (Прочитано 7059 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн SPEED

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 7
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Регулярник для замены в шаблоне
« : 26 Ноября 2006, 00:02:56 »
Есть код:

my $shablon = qq{text %%shablon_text%% text};
my $shablon_text = "замена шаблона";
my $text_shablon = $shablon;
$text_shablon =~ s/%%(.*?)%%/${$1}/ig;
print $text_shablon;

При таком раскладе в переменной $shablon не происходит замены %%shablon_text%% на нужное значение.
Если убрать my у переменной $shablon_text то все работает, но необходимо объявить переменную как my в рамках функции.
Почему не работает с my? И как быть?

Оффлайн Green Kakadu

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 2757
  • +1/-0
  • 0
    • Просмотр профиля
    • http://gnezdo.webscript.ru
Регулярник для замены в шаблоне
« Ответ #1 : 26 Ноября 2006, 00:58:47 »

#!/usr/bin/perl
use strict;


repl();

sub repl
{
    my $shablon = qq{text %%shablon_text%% text};
    my $shablon_text = "замена шаблона";
    my $text_shablon = $shablon;
    my %templates = (\'shablon_text\' =>  $shablon_text,
                     \'la\' => \'lallaalal\');
    $text_shablon =~ s/%%(.*?)%%/$templates{$1}/g;
    print $text_shablon;

}
 в исканиях.

Оффлайн SPEED

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 7
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Регулярник для замены в шаблоне
« Ответ #2 : 26 Ноября 2006, 01:32:21 »
Такой вариант был.
Однако, допустим мы не знаем какие переменные есть в шаблоне, которые надо заменять.

В таком случае нам надо дополнительно обрабатывать шаблон на получение хеша всех переменных которые там есть. Правильно?
Дополнительная обработка шаблона - это дополнительное время генерации скрипта.

А есть какие-то варианты без хеша?

И попутный вопрос. Если бы не было use strict то можно использовать local - локальное определение переменной (в рамках функции), но strict не дает использоать local.

Есть еще какие нибудь варианты?

Оффлайн SPEED

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 7
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
Регулярник для замены в шаблоне
« Ответ #3 : 26 Ноября 2006, 01:56:44 »
Если говорить о примере с хешем:

my $shablon = qq{text %%shablon_text%% %%shablon_text1%% %%shablon_text2%% text};

my $shablon_text = "замена шаблона";
my $shablon_text1 = "замена шаблона1";
my $shablon_text2 = "замена шаблона2";

my %shablon_text;

while($shablon =~ /%%(.*?)%%/ig)
{
   $shablon_text{$1} = ${$1};
}

my $text_shablon = $shablon;

$text_shablon =~ s/%%(.*?)%%/$shablon_text{$1}/ig;

print $text_shablon;


Но опять же ${$1} внутри while не заменяется на нужную переменную.

Оффлайн Green Kakadu

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 2757
  • +1/-0
  • 0
    • Просмотр профиля
    • http://gnezdo.webscript.ru
Регулярник для замены в шаблоне
« Ответ #4 : 26 Ноября 2006, 14:55:24 »
при такой записи это воспринимается как символическая ссылка, а символические ссылки обрабатываются с помощью таблицы имен пакета. Так что не получится через локальную в рамках функции ;) если только вынести функцию в отдельный пакет, и там сделать переменные глобальными.
 в исканиях.

Оффлайн Green Kakadu

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 2757
  • +1/-0
  • 0
    • Просмотр профиля
    • http://gnezdo.webscript.ru
Регулярник для замены в шаблоне
« Ответ #5 : 26 Ноября 2006, 15:12:40 »
можно конечно и так сделать

$text_shablon =~ s/%%(\\w+)%%/\'$\'.$1/gee;

но это весьма неразумно
 в исканиях.

Оффлайн Serg31416

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 18
  • +0/-0
  • 0
    • Просмотр профиля
    • http://www.cronc.com/ru.shtml
Регулярник для замены в шаблоне
« Ответ #6 : 25 Декабря 2006, 19:19:54 »
Привет.

 Лексических переменных my нет в таблице имен. Наверно, поэтому без /ee не работает.
===
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.
===
Успехов!
 Сергей cronc.com/ru.shtml

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28