计算列文件的许多行中模式的出现次数

时间:2012-08-31 10:50:03

标签: perl

我有一个列文件,如下所示

np  np  n_nom   3   {RP}    {RP}

paNiyappeVttirunna  VM_RP   V_RP    o   o   o

np  np  n_nom   -3  {/RP}   {/RP}

接下来几行......

np   np n_nom   3   {RP}    {RP}


paNiya      VM_RP     V_RP    o  o   o

np  np  n_nom   -3  {/RP}   

并且文件继续这样。

我想计算一起出现{RP} {RP}和{/ RP} {/ RP}的文件部分。

1 个答案:

答案 0 :(得分:1)

这非常简单地使用正则表达式中的反向引用

下面的程序会搜索{RP}{/RP}后面出现的一些空格和相同的字符串

它希望数据文件作为命令行参数

use strict;
use warnings;

my $count;

while (<>) {
  $count++ if m|(\{/?RP\})\s+\1|;
}

print "$count occurrences";

<强>输出

3 occurrences

<强>更新

您对此问题的描述非常不清楚,但我已尽力重新解释它。此代码查找包含{/RP} <some whitespace> {/RP}的行后面紧跟着包含{RP} <some whitespace> {RP}的行的所有情况。忽略所有空白输入行

use strict;
use warnings;

my @pair;
my $count;

while (<>) {
  next unless /\S/;
  push @pair, $_;
  next unless @pair >= 2;
  shift @pair while @pair > 2;
  if ($pair[0] =~ m|\{/RP\}\s+\{/RP\}| and $pair[1] =~ m|\{RP\}\s+\{RP\}|) {
    $count++;
    @pair = ();
  }
}

print "$count occurrences\n";

<强>输出

1 occurrences

<强>更新

好的,让我们再试一次。该程序检查每行的第三和第四个以空格分隔的列。只要它看到一对{RP}它就会$depth设置为1,并且每当它看到一对{/RP}时,它会将$ depth设置为零,递增$count如果$depth以前是非零的

请注意,只会忽略包含单个{RP}{/RP}的所有行。在这种情况下,无法从您的描述中了解您想要的行动

use strict;
use warnings;

my $depth;
my $count = 0;

while (<>) {
  my @fields = map $_ // '', (split)[4,5];
  if (grep($_ eq '{RP}', @fields) == 2) {
    $depth = 1;
  }
  elsif (grep($_ eq '{/RP}', @fields) == 2) {
    $count++ if $depth;
    $depth = 0;
  }
}

print "$count occurrences\n";

<强>输出

1 occurrences