Как я могу избежать литеральной строки, которую я хочу вставить в регулярное выражение? - PullRequest
13 голосов
/ 23 декабря 2009

Есть ли встроенный способ экранирования строки, которая будет использоваться внутри / как регулярное выражение? Э.Г.

www.abc.com

Экранированная версия будет:

www\.abc\.com

Я собирался использовать:

$string =~ s/[.*+?|()\[\]{}\\]/\\$&/g; # Escapes special regex chars

Но я просто хотел убедиться, что не хватает встроенной операции очистки, которая мне не хватает?

Ответы [ 2 ]

32 голосов
/ 23 декабря 2009

Используйте quotemeta или \Q...\E.

Рассмотрим следующую тестовую программу, которая соответствует $str как есть, quotemeta и \Q...\E:

#! /usr/bin/perl

use warnings;
use strict;

my $str = "www.abc.com";

my @test = (
  "www.abc.com",
  "www/abc!com",
);

sub ismatch($) { $_[0] ? "MATCH" : "NO MATCH" }

my @match = (
  [ as_is => sub { ismatch /$str/ } ],
  [ qmeta => sub { my $qm = quotemeta $str; ismatch /$qm/ } ],
  [ qe    => sub { ismatch /\Q$str\E/ } ],
);

for (@test) {
  print "\$_ = '$_':\n";

  foreach my $method (@match) {
    my($name,$match) = @$method;

    print "  - $name: ", $match->(), "\n";
  }
}

Обратите внимание на вывод, что использование строки как есть может привести к ложным совпадениям:

$ ./try
$_ = 'www.abc.com':
  - as_is: MATCH
  - qmeta: MATCH
  - qe: MATCH
$_ = 'www/abc!com':
  - as_is: MATCH
  - qmeta: NO MATCH
  - qe: NO MATCH

Для программ, которые принимают ненадежные входные данные, будьте предельно осторожны при использовании таких потенциально неприятных битов, как регулярные выражения: это может привести к непредвиденным ошибкам во время выполнения, уязвимостям отказа в обслуживании и дырам в безопасности.

12 голосов
/ 23 декабря 2009

Лучший способ сделать это - использовать \Q для начала строки в кавычках и \E для ее завершения.

my $foo = 'www.abc.com';
$bar =~ /blah\Q$foo\Eblah/;

Вы также можете сначала использовать quotemeta для переменной. Э.Г.

my $quoted_foo = quotemeta($foo);

Трюк \Q задокументирован в perlre в разделе «Escape-последовательности».

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