如何计算Perl中文本字符串出现的次数?

时间:2012-10-30 17:38:52

标签: perl text-manipulation

我正在尝试计算文本字符串的出现次数。

我的Perl代码在找到某些类型的文件时打印一个语句(文本字符串),我需要计算它打印字符串的次数。

elsif ($elt =~ /DELETE_.+\.XML/) {
    print "  <-- Delete XMLs !!";
}

我只是想学习perl而我不是程序员!所以请解释任何答案。

我不想插入,排序或合并,只计算。

3 个答案:

答案 0 :(得分:4)

如果要计算目录中名称与/DELETE_.+\.XML/匹配的所有文件,我会这样做:

  1. 打开目录 在Perl中,这是通过

    完成的
    opendir my $directory, "path/to/dir" or die "Error while opening: $!";
    

    然后,$directory是一个变量,表示此目录的句柄

  2. 获取目录中的所有文件 在Perl中,我们可以使用readdir函数:

    my @files = readdir $directory;
    

    这会将$directory的所有内容读入名为@files数组中。

  3. 选择与该模式匹配的所有文件 在Perl中,您可以使用grep选择满足特定条件的元素:

    my @interesting_files = grep {/DELETE_.+\.XML/} @files;
    #  ^--output                 ^--a  condition--^ ^--source
    

    我们将条件括在花括号内。它可以包含任意代码,但我们只是在这里放一个正则表达式。 grep是一种数据过滤器。

  4. 我们会计算@interesting_files中的所有元素 Perl有 context 的概念。有标量上下文列表上下文。函数和变量在每个函数中表现不同。如果在标量上下文中使用数组,则返回该数组中的元素数。我们可以使用scalar函数强制标量上下文:

    my $count = scalar @interesting_files;
    
  5. 一起形成这段代码:

    opendir my $directory, "path/to/dir" or die "Error while opening: $!";
    my @files = readdir $directory;
    my @interesting_files = grep {/DELETE_.+\.XML/} @files;
    my $count = scalar @interesting_files;
    

    如果我们省略不必要的变量并使用隐式上下文,这可以简化为以下两行。

    opendir my $directory, "path/to/dir" or die "Error while opening: $!";
    my $count = grep {/DELETE_.+\.XML/} readdir $directory;
    

    但请注意,$count只有在我们离开封闭区块({...})之后才会显示。如果您在此块之外需要$count,则必须在最外层的范围中使用my声明它。或者,您根本不使用my,但这有缺点。


    真正优雅的解决方案使用glob功能:

    my $count =()= glob "DELETE_*.XML";
    

    这抽象出手动目录的开头,并使用Unix shell中熟悉的通配语法。这些不是传统的正则表达式! =()=伪运算符可以读作 count-of 。它在右侧强加了列表上下文,但允许左侧有标量上下文。

答案 1 :(得分:2)

elsif ($elt =~ /DELETE_.+.XML/) { 
   print " <-- Delete XMLs !!";
   $count++;   # Count number of times string is printed
}

答案 2 :(得分:0)

以下内容应计算匹配的行:

use strict;
use warnings;

my $count = 0;

for (<>) {
  $count++ if /line-matches/;
}

print "count: $count\n";

如果将其放在文件count.pl中,则可以将其运行为:

perl count.pl file1 file2 file3 ...

如果你需要在管道中使用它,它也应该有效:

ls *.XML | perl count.pl