Perl 计算阵列在列文件的多行中出现的次数

Perl 计算阵列在列文件的多行中出现的次数,perl,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} 文件是这样的 我想计算

我有一个列文件如下

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}同时出现的部分的数量。

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

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

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

use strict;
use warnings;

my $count;

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

print "$count occurrences";

更新

你对这个问题的描述很不清楚,但我已经尽力重新解释了。此代码查找包含
{/RP}{/RP}
的行后面紧跟包含
{RP}{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";

更新

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

请注意,只包含单个
{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";

这段代码将计算{RP}和{/RP}的总发生次数,但我希望这两个字符串作为单个计数一起出现。因此,在上面的文件中,计数应为1,因为它们在数组[4]和数组[5]中同时出现只有一次文件中有许多句子被组织为列。因此,我想检查第5列的值是否与第4列的值相同。因此,只有第4列和第5列的值相同,并且有一个部分的RP和/RP同时出现在两列中,我的句子才是正确的。RP和/RP标记可能不在相邻的行中。中可能有许多行介于之间。我想计算两列中都包含RP和/RP的所有部分的计数。在上面的示例中,有2个部分。但我的计数是1,因为只有第一个部分的格式正确。您的描述还不够全面,但我已再次尝试解释您想要的内容。请看我的回答谢谢你的代码工作。事实上,我想计算正确标记的句子数。只有当第4列和第5列包含相同的值并且还应该包含RP和/RP标记时,句子才会正确标记。再次感谢。
1 occurrences
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