2

我正在尝试搜索和替换文件中的 URL 列表,如果搜索 URL 中有问号,我会遇到问题。下面$file只是一个标签,但通常是整个文件。

my $search = 'http://shorturl.com/detail.cfm?color=blue';
my $replace = 'http://shorturl.com/detaila.aspx?color=red';
my $file = '<a href="http://shorturl.com/detail.cfm?color=blue" class="news">HI</a>';
$file =~ s/$search/$replace/gis;
print $file;

如果$search变量中有?,则替换不起作用。如果我?color=blue要从$search变量中删除它会起作用。

有谁知道如何使上述替代工作?反斜杠,即\?没有帮助。谢谢。

4

3 回答 3

8

对正则表达式模式使用quotemeta

use warnings;
use strict;

my $search = quotemeta 'http://shorturl.com/detail.cfm?color=blue';
my $replace = 'http://shorturl.com/detaila.aspx?color=red';
my $file = '<a href="http://shorturl.com/detail.cfm?color=blue" class="news">HI</a>';
$file =~ s/$search/$replace/gis;
print $file;

__END__

<a href="http://shorturl.com/detaila.aspx?color=red" class="news">HI</a>
于 2013-07-02T13:11:16.290 回答
4

当一个字符串被插入为一个正则表达式时,它不是字面匹配的,而是被解释为一个正则表达式。这对于构建复杂的正则表达式很有用,例如

my @animals = qw/ cat dog goldfish /;
my $animal_re = join "|", @animals;

say "The $thing is an animal" if $thing =~ /$animal_re/i;

在 string$animal_re中,|被视为正则表达式元字符。

其他元字符是 eg .,它匹配任何非换行符,或者?,它使前一个原子成为可选的。

如果要按字面匹配变量的内容,可以将其括在\Q...\E引号中:

s/\Q$search/$replace/gi

(该/s选项只是将.“匹配任何非换行符”的含义更改为“匹配任何字符”,因此在这里无关紧要。)

is 函数的\Q...\E语法糖quotemeta,因此这个答案和toolic答案是完全等价的。

于 2013-07-02T13:13:23.530 回答
1

请注意,您想逃避的不仅仅是?. 在您的示例中,这?是唯一一个弄乱了您所期望的内容,但.匹配可能很难找到。

正则表达式/foo.com/确实会匹配 string foo.com,但它也会匹配foo comand fooXcomfoo!com因为.匹配任何字符。因此,/foo.com/应写为/foo\.com/

于 2013-07-02T14:27:14.567 回答