#regex #perl
#регулярное выражение #perl
Вопрос:
Я пытаюсь заменить все ` тегом HTML-кода
заменить:
$string = "Foo `FooBar` Bar";
с:
$string = "Foo <code>FooBar</code> Bar";
я пробовал эти
$pattern = '`(.*?)`';
my $replace = "<code/>$amp;</code>";
$subject =~ s/$pattern/$replace/im;
#And
$subject =~ s/$pattern/<code/>$amp;</code>/im;
но ни один из них не работает.
Комментарии:
1. Обратите внимание на косые черты.
2. Ваша строка
$string
включена, но вы выполняетеs///
on$subject
. Не могли бы вы показать свой фактический код? И не могли бы вы показать, что не работает?3. Это уценка? Если это так, взгляните на Text::Markdown .
Ответ №1:
Предполагая, что вы имели в виду $string
вместо $subject
…
use strict;
use warnings;
use v5.10;
my $string = "Foo `FooBar` Bar";
my $pattern = '`(.*?)`';
my $replace = "<code/>$amp;</code>";
$string =~ s{$pattern}{$replace}im;
say $string;
Это приводит к…
$ perl ~/tmp/test.plx
Use of uninitialized value $amp; in concatenation (.) or string at /Users/schwern/tmp/test.plx line 9.
Foo <code/></code> Bar
Здесь есть некоторые проблемы. Во-первых, $amp;
означает строку, совпадающую с последним совпадением. Это было бы все `FooBar`
. Вы просто хотите FooBar
, что находится внутри захвата скобок. Вы получите это с $1
помощью . См. раздел Извлечение совпадений в руководстве по регулярным выражениям Perl.
Во-вторых $amp;
, и $1
являются переменными. Если вы поместите их в двойные кавычки, как $replace = "<code/>$amp;</code>"
тогда, Perl немедленно интерполирует их. Это означает $replace
<code/></code>
, что . Вот откуда приходит предупреждение. Если вы хотите использовать $1
его, он должен перейти непосредственно в replace.
Наконец, при цитировании регулярных выражений лучше всего использовать qr{}
. Это приводит к специальной кавычке регулярных выражений. Это позволяет избежать всевозможных проблем с цитированием.
Соберите все это вместе…
use strict;
use warnings;
use v5.10;
my $string = "Foo `FooBar` Bar";
my $pattern = qr{`(.*?)`};
$string =~ s{$pattern}{<code/>$1</code>}im;
say $string;
Комментарии:
1. есть ли какой-либо другой способ использовать
$1
, не помещая его непосредственно в replace. например, сделать что-то вроде$replace = '<code>$i</code>'
2. @ChrysUgwu Да, но я не рекомендую это , потому что это дыра в безопасности. Если вы используете
s{}{}e
правую часть, она будет оцениваться так, как если бы это был код. Но теперь вы уязвимы для внедрения кода. Это работает как интерполяция.my $foo = 23; my $bar = q[this $foo]; print "$bar"
скажетthis $foo
. Но еслиprint eval qq["$bar"]
вы получитеthis 23
… но$bar
может содержать любой код.3. значит, Perl не предоставляет никакой защищенной замены шаблона, такой как php? php.net/manual/en/function.preg-replace.php
4. @ChrysUgwu Поиск и замена безопасны, если вы не сделаете это небезопасным. Но он не поддерживает расширение
$1
в строках, как это делает PHP в примере # 1. Возможно, это можно сделать, но я этого не знаю. Я бы предложил задать это как новый вопрос.