http://www.perlmonks.org?node_id=1016785


in reply to How to count substrings in an array?

The "goatse operator" can make this a bit shorter and faster: $count =()= $string =~ /RE/; counts the number of matches in $string, so

my $count; for(@array) { $count +=()= /RE/g; }
does what you want. It evaluates the regex in list context so it returns the list of matches and then forces it to scalar context without assigning the list anywhere.

Replies are listed 'Best First'.
Re^2: How to count substrings in an array?
by Athanasius (Archbishop) on Feb 03, 2013 at 08:20 UTC

    This works where successive matches do not overlap. But consider the case where the string to match is 'ababa' and the substring is 'aba'. The substring occurs twice in the string, but /$t/g finds only one match, because after the first match the regex engine picks up the search at the point immediately after the last match:

    ababa ^ the regex engine starts looking for the second match here

    To get overlapping matches, use a positive lookahead:

    17:58 >perl -Mstrict -wE "my $s = 'ababa'; my $t = 'aba'; my $c = () = + $s =~ /(?=$t)/g; say $c;" 2 18:02 >

    This works, because

    1. a positive lookahead is a zero-width assertion, so the first match does not consume any of the string $s; but
    2. the regex engine advances to (at least) the next character in the string following a successful match.

    See Re: Regex: finding all possible substrings by AnomalousMonk.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re^2: How to count substrings in an array?
by smls (Friar) on Feb 03, 2013 at 08:11 UTC

    Goatse operator, huh? Any idea why it isn't mentioned in perlop?

    Also, is there a way to achieve what this operator does (forced array context) without an assigment? I.e. to use inside a map { ... } without introducing temporary variables.

      > Goatse operator, huh? Any idea why it isn't mentioned in perlop?

      Maybe because the political correct name is now "Rolex operator" ? ;-)

      > I.e. to use inside a map { ... } without introducing temporary variables.

      DB<107> $s="a"x10 => "aaaaaaaaaa" DB<108> scalar ( ()= $s =~ /a/g ) => 10

      Cheers Rolf

        Rolex operator
        Are they renaming the watches to Goatse at the same time to reciprocate?
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ