It's a scoping issue. Apparently, the regex uses the variables that existed when it was first compiled, while you have declared a new set of variables on every pass. Or something like that. Anyway, this works:
my @strings = qw( aaabbbb ab abb aabb aaabb aabbb );
{
my ($a_counter, $b_counter);
for my $string ( @strings )
{
$a_counter = 0;
$b_counter = 0;
print "In $string there were $a_counter 'a's and $b_counter 'b's.
+\n" if ( $string =~ /(a(?{$a_counter ++;}))+(b(?{$b_counter ++;}))+/
+);
}
}
Caution: Contents may have been coded under pressure.