【问题标题】:How to ignore any empty values in a perl grep?如何忽略 perl grep 中的任何空值?
【发布时间】:2011-10-01 15:25:27
【问题描述】:

我正在使用以下方法来计算文件中某个模式的出现次数:

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

但有时它会比实际值多打印一。我查了一下,是因为@lines的最后一个元素为null,也算进去了。

grep 结果的最后一个元素有时怎么可能是空的?还有,这个问题怎么解决?

【问题讨论】:

  • 你为什么要给$#lines加1?
  • 在不知道模式是什么的情况下,我们没有太多机会理解为什么它在“空”行上匹配。但是,请记住,行以 \n 结尾,这被视为要匹配的内容。事实上,有些模式根本无法匹配。
  • @sergio,因为$#lines 给出了数组最后一个元素的索引(长度为 1,因为它从 0 开始)
  • @Lazer: print scalar @lines; 打印数组@lines 中有多少行。 $#lines 是顶部索引,它不是元素数量的同义词。
  • 为了让任何人都能回答这个问题,您需要指定$text 是什么。否则就像问:“我的车出了问题!怎么了?”

标签: arrays perl grep


【解决方案1】:

这在很大程度上取决于您的模式,但您可以做的一件事是加入几个匹配项,第一个匹配项取消任何仅包含空格(或不包含)的行的资格。此示例将拒绝任何为空、仅换行或仅包含任意数量的空格的行。

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

请记住,如果 $test 的内容碰巧包含正则表达式特殊元字符,则它们要么需要用于元字符目的,要么使用 quotemeta() 消毒。

我的理论是你可能有一个以 \n 结尾的行,它以某种方式匹配你的 $text 正则表达式,或者你的 $text 正则表达式包含在你不知道的情况下影响匹配的元字符。无论哪种方式,我提供的 sn-p 至少会强制拒绝“空白行”,其中空白可能意味着完全为空(不太可能)、换行符终止但否则为空(可能)或包含(可能)行时出现空白的空白打印出来的。

【讨论】:

    【解决方案2】:

    匹配空字符串的正则表达式将匹配undef。 Perl 会警告这样做,但在尝试匹配之前将undef 转换为'',此时grep 会很高兴地将undef 提升到它的结果中。如果您不想获取空字符串(或任何将被匹配为空字符串的内容),您需要重写您的正则表达式以使其不匹配。

    【讨论】:

    • 但是列表上下文 &lt;&gt; 不应该返回 undef。
    • 这很好。这意味着我在几个方面搞砸了。我希望 Lazer 能回来解释一下“null”是什么意思。
    • 我怀疑他实际上并不知道他的变量包含什么,这就是为什么我的回答是检查它:)
    【解决方案3】:

    要准确查看行中的内容,请执行以下操作:

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

    【讨论】:

    • 有一个永远不会过时的旧模块。对于调试和通常围绕数据结构包装的数据结构,Data::Dumper 是第一线工具。就在几天前,它为空白带来可见性的能力为我节省了一些时间。
    【解决方案4】:

    好的,由于没有更多关于$text(正则表达式)内容的信息即将发布,我想我会抛出一些一般信息。

    考虑以下示例:

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

    我们得到:

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

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

    你可能有这样的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      • 1970-01-01
      • 2017-01-28
      • 1970-01-01
      • 2021-11-01
      相关资源
      最近更新 更多