#regex #perl #modifier
#регулярное выражение #perl #модификатор
Вопрос:
Я пытаюсь выполнить замену некоторых переменных в строку. Хэш содержит данные, строка $name — это формат. Он вставит две переменные, но не %M. Я сбит с толку. Я пробовал два разных сигнальных символа, а также заменял их пробелами и без пробелов. %M не входит. ????
use Data::Dumper;
my %Sub = (A=>'Alan',G=>'42', M=>"Memories of Japan");
print "%Sub=n".Dumper(%Sub)."n====n";
my $name = "#M #A (#G).epub";
print "$namen====n";
$name =~ s/(#([AGM]))/($Sub{$2})/eeg;
print "$namen====n";
%Sub = (A=>'Bob',G=>'13', M=>'NightHawk');
print "%Sub=n".Dumper(%Sub)."n====n";
$name = "%M %A (%G).epub";
print "$namen====n";
$name =~ s/(%([AGM]))/($Sub{$2})/eeg;
print "$namen====n";
Комментарии:
1. Неважно… Неправильный код.
2.
$name =~ s/(%([AGM]))/($Sub{$2})/eeg;
По-прежнему не будет заменять строку пробелами.3. Это регулярное выражение соответствует любому из
A
,G
,I
([AGI]
класс символов) — нетM
…?4. Спасибо zdim. Я понял это поздно. Однако первое по-прежнему не работает со строкой с пробелами в ней.
5. Не могу сейчас написать правильный ответ… (1) нет необходимости
ee
, и это может быть очень опасно, и здесь нет необходимости даже в одномe
(2) слишком большом количестве скобок… попробуйте этот однострочный:perl -wE'$n = "#M #A (#G)"; say $n; %h = (M => "x", A => "y", G => "z"); $n =~ s/#([AGM])/#$h{$1}/g; say $n'
Ответ №1:
Вы удвоили модификатор «e» в regexpr. Кроме того, в этом примере вы можете удалить его:
use strict;
use warnings;
use Data::Dumper;
my %Sub = (A=>'Alan',G=>'42', M=>"Memories of Japan");
print "%Sub=n", Dumper(%Sub), "n====n";
my $name = "#M #A (#G).epub";
print "$namen====n";
$name =~ s/#([AGM])/$Sub{$1}/g; #<-- changed
print "$namen====n";
%Sub = (A=>'Bob',G=>'13', M=>'NightHawk');
print "%Sub=n", Dumper(%Sub), "n====n";
$name = "%M %A (%G).epub";
print "$namen====n";
$name =~ s/%([AGM])/$Sub{$1}/g; #<-- changed
print "$namen====n";
Ответ №2:
s/.../($Sub{$2})/eeg
является сокращением для
s/.../eval( ($Sub{$2}) )/eg # For each match,
# execute eval( ($Sub{$2}) )
# and use the value returned.
Вы буквально просите Perl скомпилировать и выполнить значение $Sub{$2}
как код Perl, но Memories of Japan
это (обычно) недопустимый код Perl.
Ты хочешь
s/.../$Sub{$2}/eg # For each match,
# execute $Sub{$2}
# and use the value returned.
или даже
s/.../$Sub{$2}/g # For each match,
# execute qq/$Sub{$2}/
# (equivalent to "$Sub{$2}")
# and use the value returned.
Обратите внимание, что вы всегда должны использовать use strict; use warnings;
. Это выявило бы проблему обработки NightHawk
как кода Perl.