The easiest way is not to limit the number of regex matches, but to trim the results with a list slice.
Let match global do its thing and then return the first 3 matches.
#!/usr/bin/perl -w
use strict;
my $str='dog dog horse dog cow dog pig dog';
my @dogs = ($str =~ m/dog/g)[0..2];
print "number of dogs = ".@dogs,"\n";
# the . concatenation puts @dogs in a scalar context
# same as print scalar(@dogs)
print "@dogs\n";
##################
# so what happens if there aren't 3 dogs?
# one way is to use map to filter the undef's out
# To return a "nothing at all" from map, use ()
# undef is a value and that won't work...
#
# This returns a maximum of 3 dogs if there are that
# many or more dogs, otherwise it returns less.
#
my $second_pack = "dog horse cow";
@dogs = map{$_ or ()}($second_pack =~ /dog/g)[0..2];
print "\nsecond pack = ".@dogs, " dogs\n";
print "@dogs";
__END__
number of dogs = 3
dog dog dog
second pack = 1 dogs
dog