首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何计算Perl中重叠的子字符串?

如何计算Perl中重叠的子字符串?
EN

Stack Overflow用户
提问于 2010-01-22 08:51:08
回答 5查看 1.8K关注 0票数 7

我需要在perl中实现一个程序来计算字符串中子字符串的出现次数。我按如下方式实现了它

代码语言:javascript
运行
复制
sub countnmstr
{
  $count =0;
  $count++ while $_[0] =~ /$_[1]/g;
  return $count;
}

$count = countnmstr("aaa","aa");

print "$count\n";

这就是我通常会做的事情。然而,在上面的实现中,我想要计算'aa‘在'aaa’中的出现次数。这里我得到的答案是1,这似乎是合理的,但我也需要考虑重叠的情况。因此,上面的情况应该给出一个答案为2,因为如果我们考虑重叠,则有两个‘aa’。

有没有人能建议如何实现这样的功能?

EN

回答 5

Stack Overflow用户

发布于 2010-01-22 09:21:48

每个人的答案都变得相当复杂(哦!daotoad应该把他的评论作为答案!),也许是因为他们害怕goatse操作员。我没给它起名字,这只是人们的叫法。它使用的技巧是列表赋值的结果是右侧列表中元素的数量。

用于计算匹配的Perl惯用法是:

代码语言:javascript
运行
复制
 my $count = () = $_[0] =~ /($pattern)/g;

goatse部分是= () =,它是两个赋值中间的一个空列表。山羊的左边部分从山羊的右边得到伯爵。请注意,您需要在模式中捕获,因为这是匹配操作符将在列表上下文中返回的列表。

现在,在你的例子中的下一个技巧是,你真的想要一个积极的后顾之忧(或者可能是前瞻)。lookarounds不使用字符,因此您不需要跟踪位置:

代码语言:javascript
运行
复制
 my $count = () = 'aaa' =~ /((?<=a)a)/g;

你的aaa只是一个例子。如果你有一个可变宽度的模式,你必须使用前视。Perl中的Lookbehinds必须是固定宽度的。

票数 12
EN

Stack Overflow用户

发布于 2010-01-22 17:48:42

代码语言:javascript
运行
复制
sub countnmstr
{
    my ($string, $substr) = @_;
    return scalar( () = $string =~ /(?=\Q$substr\E)/g );
}

$count = countnmstr("aaa","aa");

print "$count\n";

以下是几点:

列表上下文中的//g尽可能多地匹配。

\Q...\E用于自动转义任何元字符,以便进行子字符串计数,而不是子模式计数。

使用先行(?= ... )会导致每个匹配都不会“消耗”任何字符串,从而允许在下一个字符处尝试下面的匹配。

这使用了相同的特性,其中标量上下文中的列表赋值(在本例中为空列表)返回列表赋值右侧的元素计数作为goatse/flying lentil/spread eagle/任意操作符,但使用scalar()而不是标量赋值来提供标量上下文。

$_[0]不是直接使用的,而是复制到词法中;如果简单地使用$_[0]代替$string,如果传递的字符串具有存储的pos(),则会导致//g从字符串的中途开始,而不是从开头开始。

更新:s/g更快,尽管不如使用index快:

代码语言:javascript
运行
复制
sub countnmstr
{
    my ($string, $substr) = @_;
    return scalar( $string =~ s/(?=\Q$substr\E)//g );
}
票数 8
EN

Stack Overflow用户

发布于 2010-01-22 09:10:41

您可以在正则表达式中使用lookahead assertion

代码语言:javascript
运行
复制
sub countnmstr {
    my @matches = $_[0] =~ /(?=($_[1]))/g;

    return scalar @matches;
}

不过,我怀疑西南的建议会更快。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2114185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档