2013-12-22 125 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这样的东西,它知道所有关于特殊情况和格式。