我该如何处理Perl正则表达式中的特殊字符?

11

我正在使用Perl程序从文件中提取文本。我有一个字符串数组,用作文本的分隔符,例如:

$pat = $arr[1] . '(.*?)' . $arr[2];

if ( $src =~ /$pat/ ) {
   print $1;
}

然而,数组中的两个字符串是$450(Buy now)。这些字符串的问题在于其中的符号表示Perl正则表达式中的字符串结尾和捕获组,因此文本不会按照我的意图进行解析。

有没有什么办法解决这个问题?

3个回答

16

尝试使用Perl的quotemeta函数。或者,您可以在正则表达式中使用\Q\E来关闭正则表达式中值的插值。有关更多信息,请参见perlretut -它们可能不是您要寻找的内容。


具体而言,\Q不会保护反斜杠转义的字符。quotemeta是更通用的解决方案。 - Ben Blank
2
@BenBlank:你在说什么?\Q 编译成 quotemeta。它们是相同的函数。同样,\L 编译成 lc\U 编译成 uc,等等。\Q 完美地“保护”反斜杠转义字符,因为毕竟它就是 \Q - tchrist

11

quotemeta函数会转义元字符,以便它们被解释为字面量。作为一种快捷方式,在双引号环境中,您可以使用\Q…\E来包围应该被引用的内容:

$pat = quotemeta($arr[1]).'(.*?)'.quotemeta($arr[2]);
if($src=~$pat) { print $1 }
或者
$pat = "\Q$arr[1]\E(.*?)\Q$arr[2]";  # \E not necessary at the end
if($src=~$pat) { print $1 }
或者只是
if ( $src =~ /\Q$arr[1]\E(.*?)\Q$arr[2]/ ) { print $1 }

注意,这不仅限于插值变量;字面字符也会受到影响:

perl -wle'print "\Q.+?"'
\.\+\?

尽管显然它发生在变量插值之后,因此"\Q$foo"不会变成'\$foo'。


6

使用 quotemeta 函数:

$pat = quotemeta($arr[1]) . '(.*?)' . quotemeta($arr[2]);
if ($src =~ $pat) 
    print $1;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接