2013-12-22 163 views
0

這是我的腳本:

use strict; 
use warnings; 

while (<>) { 
    /(@.*)/; 
    print $`; 
} 

它執行正確的 - 打印方面的匹配之前的一切 - 但我得到這個:

Use of uninitialized value $` in print at FindAdd.pl line 6, <> line 1. 
Use of uninitialized value $` in print at FindAdd.pl line 6, <> line 2. 
Use of uninitialized value $` in print at FindAdd.pl line 6, <> line 3. 
Use of uninitialized value $` in print at FindAdd.pl line 6, <> line 4. 

當然,我可以如果我不使用警告,請避免這種情況,但我想知道是否有更好的方法來避免警告。 $`是否必須初始化?

+0

哪個版本的Perl在哪個平臺上?我在Mac OS X 10.9.1 Mavericks上使用了Perl 5.18.0(在10.8 Mountain Lion上編譯),並沒有從四行中得到任何警告:'aaaa @ bbbb','@ bbbb','xyz @','' abcdef'。 –

+0

我懷疑輸入與正則表達式不匹配,所以$'從未設置。不過,這不是你應該這樣做的方式。 :) –

+0

它確實匹配。你指的是什麼? –

回答

6

將您的測試移入條件。如果它不匹配,那麼$ PREMATCH變量將是未定義的。

use strict; 
use warnings; 

while (<>) { 
    if (/(\@.*)/) { 
     print $`; 
    } 
} 

此外,爲了清楚您的意圖,我會逃避@。這樣,其他人會更快地將其作爲文字讀取,而不是想知道這是否是一個數組。

+0

考慮'/(\@.*)/ p' ...'print $ {^ PREMATCH}'而不是使用$' – Kenosis

+0

甚至:'print $ \'如果/(@@.*)/' – aidan

4

每匹配變量只能通過成功的正則表達式匹配來設置(並且只能清除)。否則,它們的值將從先前成功的正則表達式匹配中遺留下來。

它看起來像你試圖匹配@(電子郵件地址可能?)之前的東西。那麼爲什麼不這樣做呢?

if (/(.*?)@/) { 
    print $1; 
} 

置身事外使用$`$&$',具有性能副作用的習慣。或者,您可以使用Perl v5.10中引入的/p標誌,該標誌具有${^PREMATCH},${^MATCH}${^POSTMATCH}這些的每個匹配版本。這些記錄在perlvar中。

如果我正在做這個任務,我會達到像Email::Address這樣的東西,它知道所有關於特殊情況和格式。