2015-07-04 46 views
2

考慮下面的代碼,爲什麼我不能在變量中存儲正則表達式?

my $string = "foo"; 
my $regex = s/foo/bar/; 
$string =~ $regex; 
print $string, "\n"; 

我本來期望的輸出爲bar,但它是foo。爲什麼會這樣,我該如何解決這個問題?

請注意,在我的實際情況下,正則表達式更復雜,我實際上希望將它們中的幾個存儲在散列表中(所以我可以寫一些類似$string =~ $rules{$key}的東西)。

+0

保存爲字符串的問題.. 。 – Proxytype

+3

務必使用'use strict;使用警告;'!它會在這裏幫助。 – ikegami

+2

's/foo/bar /'不是一個正則表達式。 –

回答

7

您正在尋找替代,不僅正則表達式的一部分,所以我想編譯正則表達式(qr//)是不是你要找什麼,

use strict; 
use warnings; 

my $string = "foo"; 
my $regex = sub { $_[0] =~ s/foo/bar/ }; 
$regex->($string); 
print $string, "\n"; 

你的陳述

my $regex = s/foo/bar/ 

被相當於

my $regex = $_ =~ s/foo/bar/ 

s///返回麻木呃進行替換,或者返回false(特別是空字符串)。所以$regex現在''1(也可能是更多,如果/g修改已生效)和

$string =~ $regex 

'foo' =~ //'foo' =~ /1/取決於什麼$_最初包含。

+0

謝謝,這是一個很好的解決方案。但我仍然想知道爲什麼我的原始代碼不起作用。 – celtschk

+0

謝謝你的解釋。 – celtschk

+0

@celtschk https://eval.in/392571如果你想要哈希規則。 –

1

在賦值中,您需要告訴Perl不要評估正則表達式,而只是爲了保留它。這是qr的用途。

但是你不能用整個替換來做到這一點,這就是爲什麼Сухой27建議使用子程序。

+1

這不是一個答案,而應該是對引用解決方案的評論 – Borodin

+0

它*是*答案:1)它回答了爲什麼給定的代碼不起作用,這是一個具體問題2)它回答了爲什麼Сухой27的解決方案是必要的。 – reinierpost

2

可以存儲在一個變量正則表達式模式,但在你的例子,正則表達式只是foo,而且有很多功能遠遠不止這些模式

聲明s/foo/bar/比更復雜的事情看起來 - 這是一個完整的聲明,它將正則表達式模式應用於目標字符串,並且如果找到該模式,則替換替換字符串。在這種情況下,目標字符串是默認變量$_,替換字符串是foo。你可以把它作爲一個調用的子程序

substitute($_, 'foo', 'bar') 

和正則表達式模式僅是第二個參數

你可以做的是存儲正則表達式。該替代的正則表達式的部分是foo,你可以說

my $pattern = qr/foo/; 

s/$pattern/bar/; 

但你真的應該解釋一下,你正在試圖解決這樣我們就可以幫助您更好地

+0

那麼,如前所述,問題是將替換正則表達式存儲在散列表中。 's/$ pattern/bar /'硬編碼替換部分。如果替換模式使用匹配引用(如'\ 1'),則將其存儲在單獨的變量中不起作用。 – celtschk

+0

@celtschk:沒有像*替換正則表達式*那樣的東西。你應該舉一個你想做什麼的例子。只是抱怨'/ /'不會得到答案。另外,如果你的意思是使用第一次捕獲,則替換字符串不應包含「\ 1」。 '\ 1'是代碼點1的字符 - 起始標題控制字符 – Borodin

相關問題