如何将我想插入的文字字符串转义为正则表达式?

时间:2009-12-22 22:52:41

标签: regex perl

是否有内置的方法来转义将在/作为正则表达式使用的字符串? E.g。

www.abc.com

转义版本将是:

www\.abc\.com

我打算用:

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

但我只是想确保我没有更清洁的内置操作?

2 个答案:

答案 0 :(得分:32)

使用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";
  }
}

请注意,在输出中使用字符串as-is可能会产生虚假匹配:

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

对于接受不值得信任的输入的程序,要非常小心地将这些可能令人讨厌的位用作正则表达式:这样做可能会产生意外的运行时错误,拒绝服务漏洞和安全漏洞。

答案 1 :(得分:12)

执行此操作的最佳方法是使用\Q开始引用字符串,使用\E结束字符串。

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

您还可以先对变量使用quotemeta。 E.g。

my $quoted_foo = quotemeta($foo);

\Q技巧记录在{Escape Sequences下的perlre中。