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

Hi guys,
I need to carry out a calculation (an increment operation within a variable) through a regular expression.

That is, everytime, a specific pattern matches, I would like to increment a counter variable.

I am imagining, the code to be something like:
 
$data=~/<BEGIN_FLAG>/$flag_count++/ ....
 
So every time the regexp encounters <BEGIN_FLAG>, it increments the $flag_count variable.

Any help would be much appreciated.

Thank you!

Replies are listed 'Best First'.
Re: Calculations in Regexp
by kennethk (Abbot) on Jan 20, 2011 at 14:35 UTC
    The easiest solution: wrap your regular expression in a while loop:

    #!/usr/bin/perl use strict; use warnings; $_ = 'aadsdfaasfga'; my $count; $count++ while /a/g; print "$count\n";

    For a shorter and more clever solution, cast the match into list context and then count the matches:

    #!/usr/bin/perl use strict; use warnings; $_ = 'aadsdfaasfga'; my $count =()= /a/g; print "$count\n";

    Finally, to literally accomplish your goal, you can embed Perl code in the regex (see A bit of magic: executing Perl code in a regular expression). There are on-point examples in the link, but I'd recommend against it.

Re: Calculations in Regexp
by toolic (Bishop) on Jan 20, 2011 at 14:35 UTC
    Here is one way:
    use warnings; use strict; my $flag_count = 0; while (<DATA>) { $flag_count++ while /<BEGIN_FLAG>/g } print "flag_count = $flag_count\n"; __DATA__ <BEGIN_FLAG> foo bar goo <BEGIN_FLAG> boo <BEGIN_FLAG> __END__ flag_count = 3
Re: Calculations in Regexp
by Anonymous Monk on Jan 20, 2011 at 14:36 UTC
    $ perldoc -q count

    Found in perlfaq4

    How can I count the number of occurrences of a substring within a stri +ng? There are a number of ways, with varying efficiency. If you want a cou +nt of a certain single character (X) within a string, you can use the "tr///" function like so: $string = "ThisXlineXhasXsomeXx'sXinXit"; $count = ($string =~ tr/X//); print "There are $count X characters in the string"; This is fine if you are just looking for a single character. However, +if you are trying to count multiple character substrings within a larger string, "tr///" won't work. What you can do is wrap a while() loop around a global pattern match. For example, let's count 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 a global match in list context, then assigns the result to a scalar, producing a count of the number of matches. $count = () = $string =~ /-\d+/g;
    perlintro
Re: Calculations in Regexp
by jethro (Monsignor) on Jan 20, 2011 at 14:42 UTC

    Why not just $flag_count++ if ($data=~/<BEGIN_FLAG>/); ?

    if you expect more than one match in a single string, check out the 'g' modifier in perlop and what it does in scalar context

    You could also use a substitution regex with ge modifier, but that sounds a bit like a hack, since you do no substitution

    PS: Is this homework, the problem seems somewhat artifical?

      Thanks for your answers!

      I am working on a large text file and putting markers around data and was trying to find out efficient ways.

      I have finally decided to use:
       
      while($data=~<BEGIN_FLAG>) {$count++;}
       
      Thank you!

        Don't forget the g modifier or this will be an endless loop. And don't forget the slashes or this won't even be a regex

        If that is what you call “efficiency,” you are barking up the wrong tree for the wrong reasons.   No matter how “large” your text file may be, the CPU will spend the vast majority of its wall-time waiting for I/O.   It will spend an insignificant amount of time incrementing a variable, or even schlepping text around in memory (as long as virtual-storage paging is not “sneaking-in a significant amount of hidden I/O”).

        What is a valid engineering concern, however, is just how easy it will continue to be to understand and to maintain your code in the future ... long after you have been smooshed (oops... hate it when that happens) by that most unfortunate bread truck.   Will your “clever trick” seem quite so clever when it turns into a bug?   Food for thought, and offered in that constructive spirit.

Re: Calculations in Regexp
by happy.barney (Friar) on Jan 20, 2011 at 15:05 UTC
    man perlre
    (?{ code }) WARNING: This extended regular expression feature is considered experi +mental, and may be changed without notice.