Добавить html в регулярное выражение perl

#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. Возможно, это можно сделать, но я этого не знаю. Я бы предложил задать это как новый вопрос.