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

Suppose I have:

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

How do I play with context to get the number of times the template found a match (3)? Can this be done with a single layer?

I tried this:

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

I thought that by putting parentheses around $number , I would forcibly use the array context, and with scalar I would get the score. However, all I get is 1 .

+74
arrays regex perl
Dec 04 '09 at 20:04
source share
9 answers

This puts the regular expression itself in a scalar context, which is not what you want. Instead, put the regular expression in the list context (to get the number of matches) and put it in a scalar context.

  my $number = () = $string =~ /\./gi; 
+111
Dec 04 '09 at 20:09
source share

I think the clearest way to describe this would be to avoid spasmodic transformations. Assign an array first, and then use this array in a scalar context. This is basically what the idiom = () = will do, but without the (rarely used) idiom:

 my $string = "one.two.three.four"; my @count = $string =~ /\./g; print scalar @count; 
+32
Dec 04 '09 at 20:17
source share

Also see Perlfaq4 :

There are several ways with different effectiveness. If you want to count a specific character (X) inside a string, you can use the tr /// function as follows:

 $string = "ThisXlineXhasXsomeXx'sXinXit"; $count = ($string =~ tr/X//); print "There are $count X characters in the string"; 

This is great if you are just looking for one character. However, if you try to count several substrings of characters in a larger string, tr /// will not work. What you can do is wrap the while () loop around global pattern matching. For example, let's consider negative integers:

 $string = "-9 55 48 -2 23 -76 4 14 -44"; while ($string =~ /-\d+/g) { $count++ } print "There are $count negative numbers in the string"; 

Another version uses global match in the context of the list, and then assigns the result to the scalar, producing the number of matches.

 $count = () = $string =~ /-\d+/g; 
+20
Dec 04 '09 at 20:20
source share

Try the following:

 my $string = "one.two.three.four"; my ($number) = scalar( @{[ $string=~/\./gi ]} ); 

He returns 3 for me. When creating a reference to an array, the regular expression is evaluated in the context of the list, and @{..} cancels the links to the array reference.

+6
Dec 04 '09 at 20:08
source share

Is the following code single-line?

 print $string =~ s/\./\./g; 
+6
Dec 05 '09 at 1:07
source share

I noticed that if your regular expression has an OR condition (for example, /(K..K)|(V.AK)/gi ), then the created array may contain undefined elements, which are included in the number at the end.

For example:

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

Gives a counter value of 6.

I found a solution in this post. How do I remove all undefs from an 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 the three.

0
Apr 02 '19 at 14:41
source share

another way,

 my $string = "one.two.three.four"; @s = split /\./,$string; print scalar @s - 1; 
-one
Dec 04 '09 at 23:56
source share

Frido Method: $a =() = $b =~ $c .

But you can simplify this even further, just ($a) = $b =~ $c , like this:

 my ($matchcount) = $text =~ s/$findregex/ /gi; 

You could thank just wrap this in the getMatchCount() function, and not worry about it destroying the passed string.

On the other hand, you can add a swap, which can be a little more computation, but does not change the line.

 my ($matchcount) = $text =~ s/($findregex)/$1/gi; 
-one
Oct 23 '15 at 15:13
source share
 my $count = 0; my $pos = -1; while (($pos = index($string, $match, $pos+1)) > -1) { $count++; } 

checked with benchmark, it's pretty fast

-one
May 09 '18 at
source share



All Articles