delete[]
вызовет деструктор каждого элемента массива.
Именно поэтому используются интеллектуальные указатели: delete[]
вызовет деструктор каждого элемента, а деструктор - умного указателя вызовет delete
на управляемом указателе.
Итак: узнайте о умных указателях и прекратите управлять памятью вручную. Это проще, меньше подверженности ошибкам и менее низкого уровня.
На заменяющей стороне необходимо использовать 1$, не \1.
И можно только сделать то, что Вы хотите путем создания замены evalable выражением, которое дает результат, который Вы хотите и говорящий s///к оценке она с/ee модификатором как так:
$find="start (.*) end";
$replace='"foo $1 bar"';
$var = "start middle end";
$var =~ s/$find/$replace/ee;
print "var: $var\n";
Для наблюдения, почему "" и удваивают/e, необходимы, видят эффект двойной оценки здесь:
$ perl
$foo = "middle";
$replace='"foo $foo bar"';
print eval('$replace'), "\n";
print eval(eval('$replace')), "\n";
__END__
"foo $foo bar"
foo middle bar
(Хотя как ikegami примечания, единственный/e или первый/e двойного e не действительно eval()
; скорее это говорит компилятору, что замена является кодом для компиляции, не строка. Тем не менее, eval(eval(...))
все еще демонстрирует, почему необходимо сделать то, что необходимо сделать, чтобы заставить/ee работать, как желаемый.)
Я не уверен относительно того, что это, Вы пытаетесь достигнуть. Но возможно можно использовать это:
$var =~ s/^start/foo/;
$var =~ s/end$/bar/;
Т.е. просто оставляют середину в покое и заменяют запуск и конец.
Deparse говорит нам, что это - то, что выполняется:
$find = 'start (.*) end';
$replace = "foo \cA bar";
$var = 'start middle end';
$var =~ s/$find/$replace/;
Однако
/$find/foo \1 bar/
Интерпретируется как:
$var =~ s/$find/foo $1 bar/;
К сожалению, кажется, что нет никакого простого способа сделать это.
Можно сделать это со строковой оценкой, но это опасно.
Самое нормальное решение, которое работает на меня, было этим:
$find = "start (.*) end";
$replace = 'foo \1 bar';
$var = "start middle end";
sub repl {
my $find = shift;
my $replace = shift;
my $var = shift;
# Capture first
my @items = ( $var =~ $find );
$var =~ s/$find/$replace/;
for( reverse 0 .. $#items ){
my $n = $_ + 1;
# Many More Rules can go here, ie: \g matchers and \{ }
$var =~ s/\\$n/${items[$_]}/g ;
$var =~ s/\$$n/${items[$_]}/g ;
}
return $var;
}
print repl $find, $replace, $var;
Как я сказал в своем ответе, я избегаю evals по причине.
$find="start (.*) end";
$replace='do{ print "I am a dirty little hacker" while 1; "foo $1 bar" }';
$var = "start middle end";
$var =~ s/$find/$replace/ee;
print "var: $var\n";
этот код делает точно, что Вы думаете, что он делает.
Если Ваша строка замены находится в веб-приложении, Вы просто открыли дверь в выполнение произвольного кода.
Хорошее задание.
Кроме того, это не будет работать с инфекциями, включенными по этой самой причине.
$find="start (.*) end";
$replace='"' . $ARGV[0] . '"';
$var = "start middle end";
$var =~ s/$find/$replace/ee;
print "var: $var\n"
$ perl /tmp/re.pl 'foo $1 bar'
var: foo middle bar
$ perl -T /tmp/re.pl 'foo $1 bar'
Insecure dependency in eval while running with -T switch at /tmp/re.pl line 10.
Однако более осторожная техника нормальна, безопасна, безопасна, и не приводит инфекцию к сбою. (Уверьте tho, строка, которую он испускает, все еще испорчена, таким образом, Вы не теряете безопасности.)
Я бы предложил бы что-то вроде:
$text =~ m{(.*)$find(.*)};
$text = $1 . $replace . $2;
это довольно читаемо и кажется, безопасно. Если необходима несколько замене, это легко:
while ($text =~ m{(.*)$find(.*)}){
$text = $1 . $replace . $2;
}
См. ЭТО предыдущий пост SO об использовании переменной на стороне замены s ///
в Perl. Посмотрите как на принятый ответ , так и на опровержение .
То, что вы пытаетесь сделать, возможно с помощью формы s /// ee
, которая выполняет двойной eval
в правой строке. Дополнительные примеры см. В perlop quote like операторах .
Имейте в виду, что существуют угрозы безопасности eval
, и это не будет работать в режиме заражения.
#!/usr/bin/perl
$sub = "\\1";
$str = "hi1234";
$res = $str;
$match = "hi(.*)";
$res =~ s/$match/$1/g;
print $res
Это дало мне '1234'.
# perl -de 0
$match="hi(.*)"
$sub='$1'
$res="hi1234"
$res =~ s/$match/$sub/gee
p $res
1234
Но будьте осторожны. Это вызывает появление двух уровней eval
, по одному для каждого e
в конце регулярного выражения: