Нет компиляции для выражения замены.Так что, единственное, что вы можете сделать, это exec или eval с флагом e
:
if($test =~ s/$regex/eval qq["$hash->{subs}"]/e ) { #...
работал для меня после изменения \\1
на \$1
в строках замены.
s/$regex/$hash->{subs}/
заменяет только совпадающую часть на значение литерал , сохраненное в $hash->{subs}
как полное замещение.Чтобы заставить подстановку работать, вы должны заставить Perl вычислять строку как строку , что означает, что вам даже нужно добавить кавычки обратно, чтобы получить искомое интерполяционное поведение(потому что они не являются частью строки.)
Но это немного неуклюже, поэтому я изменил выражения замены на подпрограммы:
my @Special_Regex
= (
{ regex => qr{\s*element\s+/my_elem_removed\s*/main/\d+$}
, subs => sub { '#Line removed' }
}
, { regex => qr{\s*element\s+/my_elem_changed/releases/\.\.\.\s*(.*$)}
, subs => sub {
return "element -directory /my_elem/releases/... $1\n"
. "element /my_elem/releases/.../*.[ch] $1"
;
}
}
);
Я избавился от множества вещей, которыевам не нужно убегать в выражении подстановки.Поскольку вы хотите интерполировать значение $1
в строку замены, подпрограмма делает просто .И поскольку $1
будет отображаться до тех пор, пока не будет найдено что-то еще, это будет правильное значение, когда мы запустим этот код.
Итак, теперь замена выглядит следующим образом:
s/$regex/$hash->{subs}->()/e
Конечно, делая это pass $1
делает его немного более пуленепробиваемым, потому что вы не зависите отглобальный $1
:
s/$regex/$hash->{subs}->( $1 )/e
Конечно, вы бы изменили саб так, как:
subs => sub {
my $c1 = shift;
return "element -directory /my_elem/releases/... $c1\n"
. "element /my_elem/releases/.../*.[ch] $c1"
;
}
Только одна последняя заметка: "\.\.\."
не сделал то, что вы думаетеэто сделал.Вы только что получили в регулярном выражении '...'
, что соответствует любым трем символам.