Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Count number of occurrences of a substr

by Jerbear217 (Initiate)
on Sep 28, 2011 at 18:27 UTC ( #928383=perlquestion: print w/replies, xml ) Need Help??

Jerbear217 has asked for the wisdom of the Perl Monks concerning the following question:

Hi. I'm trying to write a conditional based on the number of occurrences of $sub in a constant string.

I couldn't find a concise solution on perldoc, though there was an alternative where a loop was used. This says m// is meant to return the number of matches. It doesn't seem to do that. The test code below is what they have in their s/// example, except with m instead of s.

my $str = "thisthis"; if ( my $n = ($str =~ m/this/g) ) { print qq{Found $n occurrence(s) of "this"\n}; }

This outputs "Found 1 blah".

Some context (pun not intended) might help. Essentially, I want to code "If $sub occurs more than N times in '<string>', then do something". I can think of a lot of bad ways to do this, but not a good way to do it.

In the following extract, we're trying to print "Yes" if "" occurs more than N times in the output of some command. There's a useless array there to gather the results in a list, the length of which being what I want to base a decision on.

print "Yes" if( (my @a = `route print`=~ m!!g) > 3);

Is there a nice (ie, without my useless @a) way to return the number of matches from the regex search?

Thanks for your time

Update: Thanks all. Good answers all round. Helpful and concise (how perl should be :D). I'm not sure what the thanking protocol is here...didn't want to create a new reply D:

Replies are listed 'Best First'.
Re: Count number of occurrences of a substr
by toolic (Bishop) on Sep 28, 2011 at 18:47 UTC
Re: Count number of occurrences of a substr
by ikegami (Pope) on Sep 28, 2011 at 18:45 UTC

    Well, you could use a useless assignment to (). Except it's not useless. As you've already demonstrated, a list assignment in scalar context returns the number of scalars returned by its RHS.

    ( my @a = `route print`=~ m!!g ) > 3
    can be shortened to
    ( () = `route print`=~ m!!g ) > 3
    and broken
    my $n = $str =~ m/this/g;
    should be changed to one of
    my $n = () = $str =~ m/this/g; my $n = grep 1, $str =~ m/this/g; my $n = map $_, $str =~ m/this/g;
    Some might prefer
    my $n = 0; ++$n while $str =~ m/this/g;
Re: Count number of occurrences of a substr
by aaron_baugher (Curate) on Sep 28, 2011 at 19:10 UTC

    That page you referenced isn't quite right. The m// operator never returns the number of matches. In scalar context, it returns true (1) if the match succeeds or false if it doesn't. In list context, it returns a list of matches, which you can turn into a count by passing it through an anonymous list:

    #!/usr/bin/perl use Modern::Perl; my $str = 'thisthis'; my $n = $str =~ /this/g; say $n; $n = $str =~ /that/g; say $n; ($n) = $str =~ /this/g; say $n; $n = () = $str =~ /this/g; say $n; #output 1 this 2

    The s/// operator, on the other hand, does return the number of matches, regardless of whether it's called in scalar or list context.

Re: Count number of occurrences of a substr
by hbm (Hermit) on Sep 28, 2011 at 18:45 UTC

    Here are two ways of counting matches:

    $n++ while $str=~/this/g; $str =~ /this(?{$n++})(*F)/;
      Note, $n needs to be a local our $n; instead of my $n; for the second snippet to work properly in a sub.
Re: Count number of occurrences of a substr
by Anonymous Monk on Sep 29, 2011 at 14:39 UTC
    Also notice the somewhat-obscure regex modifiers ("m," "i," and "g" seem to come to mind) that allow you to repeatedly match within a single string. The "position" where matching is to start (or resume) can be controlled precisely. It's somewhat obscure and therefore feels a bit like voodoo, but it's not.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://928383]
Approved by toolic
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2021-12-09 14:45 GMT
Find Nodes?
    Voting Booth?
    R or B?

    Results (36 votes). Check out past polls.