2016-11-15 76 views
0

我試圖找出爲什麼這是工作:Perl的操作符/// G未按預期

$_='12+34';$x=1; 
s/(\d+)(.)(\d+)/"\$x$2$2"/ee; # This is working, does $x++ 

print "x=$x \n";    # x=2 

雖然這不是:

$_='12+34';$x=1; 
s/(\d+)(.)(\d+)/\$x$2$2/e; # This is NOT working 

# Error message is : 
# Scalar found where operator expected at ./test.pl line 2, near "$x$2" 
#  (Missing operator before $2?) 

我有膽量說s/xxx/yyy/es/xxx/"yyy"/ee應該表現相同,但顯然我錯了。

我缺少什麼?

回答

7

你誤解表達改性劑 - 單個/e

它使替換串被視爲一個Perl表達,並且是基本上爲標準模式的替代,這是爲了處理字符串就好像它是用雙引號

通常

my $x = 1; 
my $y = '12+34'; 

$y =~ s/(\d+)(.)(\d+)/\$x$2$2/; 

產生replacem耳鼻喉科等價的字符串qq{\$x$2$2},這是$x++

如果添加/e則替換被視爲一個Perl的表達,你得到錯誤,因爲\$x$2$2是無效的Perl。您可以通過使用

s/(\d+)(.)(\d+)/'$x' . $2 . $2/e 

像以前一樣得到同樣的結果,或如你所看到的,字符串表達式

s/(\d+)(.)(\d+)/"\$x$2$2"/e 

但是,所有這些要做的就是評估Perl的表達。沒有辦法在不添加第二/e改性劑,其代表EVAL

所得/ee導致Perl來對待替換作爲表達以執行從目標串的部分構成任意Perl碼(代替這樣做就可以了雙引號插值),然後EVAL表達式的結果

例如

s/(\d+)(.)(\d+)/'$x' . $2 . $2/ee 

首先計算表達式'$x' . $2 . $2$x++,然後做eval該字符串,返回1(這樣原12+34替換1)和遞增$x

您可以使用表達模式單一/e如果你可以寫一個Perl表達式,可以滿足你的需求。否則,你需要使用/ee得到一個EVAL階段以及

我認爲這是更清楚,如果你涉及/e在所有使用大括號。這樣它看起來像Perl代碼而不是字符串替換

s{(\d+)(.)(\d+)}{ 
    '$x' . $2 . $2 
}ee 
+0

Correcto !! '/ ee' double評估RHS – 2016-11-15 13:33:54

+1

@Gerry:*錯誤!*我竭盡全力解釋第一個'/ e'將替換視爲*表達式*。它不會「評估」任何東西。第二個'/ e'將'eval'表達式的值 – Borodin

+0

完美答案。現在更清楚了。我錯過了替換部分嵌入在使用/// e修飾符時不存在的不可見qq {...}的事實。謝謝。 –