Is there a Perl shortcut to count the number of matches in a string?

Viewed 65710

Suppose I have:

my $string = "one.two.three.four";

How should I play with context to get the number of times the pattern found a match (3)? Can this be done using a one-liner?

I tried this:

my ($number) = scalar($string=~/\./gi);

I thought that by putting parentheses around $number, I'd force array context, and by the use of scalar, I'd get the count. However, all I get is 1.

9 Answers

I noticed that if you have an OR condition in your regular expression (eg /(K..K)|(V.AK)/gi ) then the array produced may have undefined elements which are included in the count at the end.

For example:

my $seq = "TSYCSKSNKRCRRKYGDDDDWWRSQYTTYCSCYTGKSGKTKGGDSCDAYYEAYGKSGKTKGGRNNR";
my $regex = '(K..K)|(V.AK)';
my $count = () = $seq =~ /$regex/gi;
print "$count\n";

Gives a value of count of 6.

I found the solution in this post How do I remove all undefs from array?

my $seq = "TSYCSKSNKRCRRKYGDDDDWWRSQYTTYCSCYTGKSGKTKGGDSCDAYYEAYGKSGKTKGGRNNR";
my $regex = '(K..K)|(V.AK)';
my @count = $seq =~ /$regex/gi;
@count = grep defined, @count; 
my $count = scalar @count;
print "$count\n";

Which then gives the correct answer of three.

my $count = 0;
my $pos = -1;
while (($pos = index($string, $match, $pos+1)) > -1) {
  $count++;
}

checked with Benchmark, it's pretty fast

Related