2011-07-08 16 views
6

我使用下面的计算文件中的一个模式的出现次数:如何忽略perl grep中的任何空值?

my @lines = grep /$text/, <$fp>; 
print ($#lines + 1); 

但有时它打印比实际值多一个。我检查了这是因为@lines的最后一个元素为空,这也是计数。

grep结果的最后一个元素如何有时会变空?另外,如何解决这个问题?

+0

你为什么要给'$#lines'加1? – sergio

+3

不知道模式是什么,我们没有太多的机会理解它为什么匹配在“空行”。但是,请记住,以\ n结尾的行数将视为匹配的内容。事实上,一些模式可以完全匹配。 – DavidO

+0

@sergio,因为'$#lines'给出数组最后一个元素的索引(从0开始的长度为1) – Lazer

回答

6

它确实取决于你的模式,但你可以做的一件事就是加入几个匹配,第一个匹配任何只包含空格(或不包含空格)的行。这个例子将拒绝任何只有空行,只有换行符或任何数量的空白行。

my @lines = grep { not /^\s*$/ and /$test/ } <$fp>; 

请记住,如果$测试的内容碰巧包括他们要么需要被用于他们的元字符目的,或与quotemeta()消毒的正则表达式特殊的元字符。

我的理论是,你可能在\ n中有一行以某种方式与你的$ text正则表达式匹配,或者你的$ text正则表达式中包含的元字符会影响匹配而你没有意识到。无论哪种方式,我提供的片段至少会强制拒绝“空白行”,其中空白可能意味着完全空白(不太可能),换行符终止,否则为空(很可能),或空白包含打印时显示空白的(可能的)行。

2

匹配空字符串的正则表达式将匹配undef。 Perl会警告这样做,但在试图与之匹配之前将undef改为'',此时grep将非常高兴地将undef提升为其结果。如果您不想拾取空字符串(或任何与空字符串相匹配的字符串),则需要重写正则表达式以使其不匹配。

+0

,但是列表上下文'<>'不应该返回undef。 – ysth

+0

这是一个很好的观点。这意味着我以几种方式搞砸了。我希望拉泽尔会回来解释'空'的含义。 – darch

+0

我怀疑他实际上并不知道他的变量包含什么,这就是为什么我的答案是检查它:) – ysth

2

要准确地看到什么是线,这样做:

use Data::Dumper; 
$Data::Dumper::Useqq = 1; 
print Dumper \@lines; 
+0

有一个旧模块,永远不会变老。对于调试和通常在数据结构中环绕头部,Data :: Dumper是第一线工具。就在几天前,它将能见度留给空白的能力为我节省了一些时间。 – DavidO

0

好吧,距今约$text(正则表达式)的内容没有更多的信息是即将到来的,我想我会折腾出一些常规信息。

请看下面的例子:

use Data::Dumper; 

my @array = (' ', 1, 2, 'a', ''); 
print Dumper [ grep /\s*/, @array ]; 

我们得到:

$VAR1 = [ 
      ' ', 
      1, 
      2, 
      'a', 
      '' 
     ]; 

所有值匹配。为什么?因为它们也匹配空字符串。为了得到我们想要的,我们需要\s\s+。 (两者之间没有实际区别)

您可能有这样的问题。