计算另一个(Perl)内的字符串出现次数

ron*_*ash 34 regex perl substring

计算某个字符串出现在较大字符串中的次数的最快方法是什么?我最好的猜测是用任何东西替换该字符串的所有实例,计算长度的差异并除以子字符串的长度,但这似乎相当慢,我需要分析大量数据.

TLP*_*TLP 63

您可以捕获字符串,然后计算它们.可以通过将列表上下文应用于捕获来完成():

my $x = "foo";
my $y = "foo foo foo bar";
my $c = () = $y =~ /$x/g;  # $c is now 3
Run Code Online (Sandbox Code Playgroud)

您还可以捕获到数组并计算数组.原理相同,技术不同:

my @c = $y =~ /$x/g;
my $count = @c;
Run Code Online (Sandbox Code Playgroud)

  • @ronash这是同样的解决方案.一个使用临时变量,另一个不使用.你也可以做'我的$ count = @c = $ y =〜/ $ x/g`,但你可以简单地忽略`@ c`并使用`()`.如果你不关心实际比赛,哪个是最好的. (2认同)
  • 如果`$ x`包含某些正则表达式字符,这不起作用,因为`$ x`被解释为正则表达式.添加`\ Q`来修复此问题,例如.`/\Q $ X/g`.有关更多信息,请参阅`quotemeta`. (2认同)

Bri*_*ach 15

my $string = "aaaabbabbba";
my @count = ($string =~ /a/g);
print @count . "\n";
Run Code Online (Sandbox Code Playgroud)

要么

my $count = ($string =~ s/a/a/g);
Run Code Online (Sandbox Code Playgroud)


Mat*_*eck 9

您可以使用全局正则表达式.就像是:

my @matches = $bigstring =~ /($littlestring)/g;
my $count = @matches;
Run Code Online (Sandbox Code Playgroud)


Mat*_*ock 5

仅出于完整性考虑,您可以在循环中重复调用index函数,并计算它返回字符串中子字符串索引的所有次数,并更改起始位置。这样可以避免使用正则表达式,并且在我的测试中,它比正则表达式解决方案要快一些。

我已经从此处改编了一个子程序:http : //www.misc-perl-info.com/perl-index.html

sub occurrences {

    my( $x, $y ) = @_;

    my $pos = 0;
    my $matches = 0;

    while (1) {
        $pos = index($y, $x, $pos);
        last if($pos < 0);
        $matches++;
        $pos++;
    }   

    return $matches;
}
Run Code Online (Sandbox Code Playgroud)