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

Jam*_*mes 13 regex perl

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

www.abc.com
Run Code Online (Sandbox Code Playgroud)

转义版本将是:

www\.abc\.com
Run Code Online (Sandbox Code Playgroud)

我打算用:

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

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

Gre*_*con 32

使用quotemeta\Q...\E.

考虑以下测试程序,该程序与$stras-is,with quotemeta和with 匹配\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";
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意,在输出中使用字符串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

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


fri*_*edo 12

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

my $foo = 'www.abc.com';
$bar =~ /blah\Q$foo\Eblah/;
Run Code Online (Sandbox Code Playgroud)

您也可以先使用quotemeta变量.例如

my $quoted_foo = quotemeta($foo);
Run Code Online (Sandbox Code Playgroud)

在"Escape Sequences"下的perlre中\Q记录了这个技巧.