Почему $ _ = ~ "регулярное выражение" допустимо в Perl? - PullRequest
0 голосов
/ 22 сентября 2018

Я знаю в Perl, наиболее распространенное правильное регулярное выражение выглядит так:

$_ =~ m/regular expression/;

# and "m" can be omit
$_ =~ /regular expression/;

И я могу использовать qr для создания ссылки на регулярное выражение, например:

my $regex = qr/regular expression/;
$_ =~ m/$regex/;

# and "m//" can be omit:
$_ =~ $regex;

Но я попробовал это:

my $str = "regular expression";
$_ =~ $str; # why this is valid?

Это не дало мне никакой информации об ошибке и работало нормально.Я не знаю почему, я думаю, что это должно быть похоже на

my $str = "regular expression";
$_ =~ m/$str/;

# or
my $str = "regular expression";
my $regex = qr/$str/;
$_ =~ $regex;

Может кто-нибудь объяснить, почему $_ =~ $str действует в Perl?

Ответы [ 3 ]

0 голосов
/ 22 сентября 2018

В perlre указано «Основы»

Шаблоны, которые еще не сохранены в какой-либо переменной, должны быть разделены на обоих концах символами-разделителями.

(вместе с ошибочным tt`)

Таким образом, шаблон в переменной просто не нуждается в разделителях.Оператор =~, обсуждаемый в "Операторы связывания" в perlop

, привязывает скалярное выражение к сопоставлению с шаблоном.

и (с моимвыделение)

Если правильный аргумент является выражением, а не шаблоном поиска, подстановкой или транслитерацией, он интерпретируется как шаблон поиска во время выполнения.

Оператор не заботится о разделителях в правой части, и «выражение регулярного выражения» может быть сформировано во время выполнения из выражения.

Раздел "Gory детали синтаксического анализа цитируемых конструкций" в perlop также помогает в этом, кроме того, что освещает сам по себе.После идентификации цитируемой конструкции и интерполяции содержащегося в ней текста она попадает в пул "синтаксический анализ регулярных выражений"

После предварительной обработки, описанной выше ... результирующая строка передается вДвижок RE для компиляции.

(мой акцент)

Это общее обсуждение того, как Perl обрабатывает цитируемые конструкции, и нет необходимости в (дополнительных) разделителях после формирования строкииз цитируемой конструкции.m/RE/ (и т. Д.) Обсуждались ранее в пуле " interpolation ", который показывает некоторые вещи, которые нельзя использовать с простой строкой для шаблона, но это явно не обязательно дляиметь.

Я бы рекомендовал против этого, хотя;используйте qr, как вы ожидаете.Во-первых, использование строки (а не регулярного выражения, созданного с qr) является ограничением.Кроме того, это более склонно к глупым ошибкам.


Обратите внимание, что хотя для многих шаблонов , можно использовать qr или "" (или его операторную форму qq()) для подготовки шаблона (или строки, котораябудет интерпретироваться таким образом) - они не одинаковы.Их правила цитирования довольно схожи, но qr готовит регулярное выражение , которое, как указано в Операторы, подобные цитате Regexp

... магическиотличается от строки, содержащей те же символы ...

Напомним, что для qr вы можете использовать модификаторы.

0 голосов
/ 22 сентября 2018

На это отвечает документация для =~ в perlop :

Если правильный аргумент является выражением, а не шаблоном поиска, подстановкой или транслитерацией, онинтерпретируется как шаблон поиска во время выполнения.


Есть только несколько вещей, которые могут законно следовать =~:

  • Оператор соответствия (m//)
  • Оператор подстановки (s///)
  • Оператор транслитерации (tr///)

Теперь Perl может выдайте синтаксическую ошибку, как вы ожидаете, если что-нибудь еще, если она найдена в правой части =~.Но вместо этого он делает что-то гораздо более полезное.Если он находит что-то отличное от вышеприведенных операторов, результат выражения используется в качестве шаблона для оператора неявного соответствия.

Это удобно позволяет

$s =~ get_pattern()               # do { my $pat = get_pattern(); $s =~ /$pat/ }

и

$s =~ ( $sub_pat1 . $sub_pat2 )   # do { my $pat = $sub_pat1 . $sub_pat2; $s =~ /$pat/ }
0 голосов
/ 22 сентября 2018

Perl стремится быть естественным языком, поэтому такие привычные формы '' и "" могут иметь различные общие формы в зависимости от контекста.Вот таблица, взятая прямо из Программирование на Perl, 4-е издание (стр. 71) , Таблица 2-7.Конструкции с кавычками:

+-----------+---------+-----------------------+--------------+
| Customary | Generic | Meaning               | Interpolates |
+-----------+---------+-----------------------+--------------+
| ''        | q//     | Literal string        | No           |
+-----------+---------+-----------------------+--------------+
| ""        | qq//    | Literal string        | Yes          |
+-----------+---------+-----------------------+--------------+
| ``        | qx//    | Command execution     | Yes          |
+-----------+---------+-----------------------+--------------+
| ()        | qw//    | Word list             | No           |
+-----------+---------+-----------------------+--------------+
| //        | m//     | Pattern match         | Yes          |
+-----------+---------+-----------------------+--------------+
| s///      | s///    | Pattern substitution  | Yes          |
+-----------+---------+-----------------------+--------------+
| tr///     | y///    | Character translation | No           |
+-----------+---------+-----------------------+--------------+
| ""        | qr//    | Regular expression    | Yes          |
+-----------+---------+-----------------------+--------------+

Пример:

В этом примере строка преобразуется в шаблон.Здесь вы должны позаботиться, потому что, когда вы создаете шаблоны из строк в двойных кавычках, вы должны избегать косой черты.

Вы можете ясно увидеть здесь:

my $pat = "hello\\s+world"; #double-slash to escape the slash

if ("hello       world" =~ $pat) {
    print "hello, world\n";
}

output:

hello, world
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...