in reply to How can I access the number of repititions in a regex?

Consider:

my $str = "12345"; my $count = () = $str =~ /\d/g; print $count;

Prints:

5

The () = puts the regex into list context, then the scalar assignment, as is usual, assigns the countof the items in the list.


Perl is environmentally friendly - it saves trees

Replies are listed 'Best First'.
Re^2: How can I access the number of repititions in a regex?
by amarquis (Curate) on Mar 11, 2008 at 18:42 UTC

    Would you mind explaining how this works? I understand that the empty () imposes list context on the right, making the match return the number of matches.

    Then you are left with the assignment of a scalar to an empty list, which is in turn assigned to $count. I guess I'm just not sure how the "5" propagates over the empty list in the middle to land in the $count variable.

    Sorry if I'm being dense.

      I understand that the empty () imposes list context on the right...
      correct
      ...making the match return the number of matches.
      Not quite. The match returns a list of matches. A list assignment in scalar context returns the number of elements in the list, regardless of the number of those elements that actually get assigned to anything (in this case, zero). So the "5" doesn't propagate. It's the use of the assignment in scalar context that creates the "5".
        Ah, thank you. Sorry, I don't know why I was confusing the two, it doesn't even make sense the way I was thinking about it.
Re^2: How can I access the number of repititions in a regex?
by pat_mc (Pilgrim) on Mar 11, 2008 at 13:45 UTC
    Thanks, GrandFather - I got that.
    Nice solution ... though subject to the same limitations as the one by olus above. What if I want to evaluate multiple quantifiers in the same regex?

      There is such possibility, but using 'highly experimental' :) code:

      $_='this is some text(55). this is another text. there are 2 texts.'; @re=/text(?{$cnt1++})|\d+(?{$cnt2++})/g; print "'text' occured $cnt1 times\n"; print "'\\d+' occured $cnt2 times\n";

      But there are some problems: what if one of your regexps is part of another one?

        Good stuff, grizley!

        Thanks for throwing code evaluation expressions into the race ... they offer exactly the range of flexibility I need to solve my class of problems ... and - as you can tell by the date on this post - it took me quite some time to realise (a) what they are and (b) how they work.

        Your help is much apprecicated!

        Best regards -

        Pat
      quantifiers are ?, *, +, and {}, so you're not talking about quantifiers
        Oh yes, I am.

        Consider this:
        while ( <> ) { print $a_counter, $b_counter if /a+b+/; }


        with an input like "aaabb" I would expect an output like
        3 2

        Know what I mean?

        Thanks again for taking the time to comment. Your help is much appreciated!
array and list return different things in scalar context
by metaperl (Curate) on Mar 11, 2008 at 14:44 UTC
    The () = puts the regex into list context, then the scalar assignment, as is usual, assigns the countof the items in the list.
    An array returns its weight, a list returns its last... a list in scalar context returns its last element, not the count of elements.

      a list in scalar context returns its last element

      There's a somewhat detailed discussion of what's wrong with this idea starting about here. Here's one problem with it:

      my @x = ( 6, 7, 8 ); my $last_element = (4, 5, @x)[-1]; my $as_scalar = (4, 5, @x); print "last element: $last_element\n"; print "as scalar: $as_scalar\n"; __END__ last element: 8 as scalar: 3

      One might say that the scalar context is applied to the last element of the list expression (not the list itself). Note that scalar sub_that_returns_list() will apply the scalar context to everything in the sub's return list, but scalar ( 'literal', 'list', 'expression' ) puts 'literal' and 'list' in void context.

      This isn't a "list in scalar context", it's a list assignment in scalar context, which has a very well-defined behavior: it returns the number of elements in the list on the right side of the assignment operator.