2013-07-02 55 views
2

我正在嘗試搜索並替換文件中的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變量?在它的替代不起作用。如果我要從$search變量中取出?color=blue,它會起作用。

有誰知道如何使上述替代工作?反斜槓,即\?沒有幫助。謝謝。

回答

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...\E是爲quotemeta功能語法糖,因此這個答案,toolicanswer是完全等價的。

+0

@devnull無論如何,模式終止時,結束'\ E'是可選的。 – amon

+0

謝謝。 quotemeta就像那樣添加了meta標籤。因爲我正在搜索一個文件,而不僅僅是一行。該示例僅使用一行簡短。再次感謝。 –

1

請注意,您想逃離的不僅僅是?。在你的例子中,?是唯一一個弄亂你所期望的,但.匹配可能是陰險的發現。

正則表達式/foo.com/的確會匹配字符串foo.com,但它也將匹配foo comfooXcomfoo!com,因爲.任何字符匹配。因此,/foo.com/應寫爲/foo\.com/