如何匹配问号?

时间:2013-07-02 13:06:12

标签: regex perl

我正在尝试搜索并替换文件中的网址列表,如果搜索网址中有问号,我就会遇到问题。下面的$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,它会起作用。

有谁知道如何进行上述替换工作?反斜杠,即\?没有帮助。感谢。

3 个答案:

答案 0 :(得分: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>

答案 1 :(得分:4)

当字符串被插值为正则表达式时,字面上不匹配,而是解释为正则表达式。这对于构建复杂的正则表达式非常有用,例如

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

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

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

其他元字符例如是.,匹配任何非换行符,或?,使前一个原子可选。

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

s/\Q$search/$replace/gi

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

\Q...\Equotemeta函数的语法糖,因此这个答案与toolicanswer完全相同。

答案 2 :(得分:1)

请注意,您想要逃避的不仅仅是??是您示例中唯一会弄乱您所期望的内容的.,但/foo.com/匹配可能会隐藏起来。

正则表达式foo.com确实会匹配字符串foo com,但它也会匹配fooXcomfoo!com以及.,因为/foo.com/匹配任何角色。因此,/foo\.com/应写为{{1}}。