The only thing I would add to choroba's comprehensive comments is that you might consider adding some kind of boundary assertion to the fin delimiter pattern: see what happens when the \b assertion in the match used below is omitted. I agree that the look-arounds don't seem needed, so I've left them out. (I use \x23 instead of # in my pattern only because my REPL doesn't like octothorpes.)
c:\@Work\Perl\monks>perl -wMstrict -le
"use 5.010;
;;
my @lines = (
'The 2 cats and the dog.',
'The 8 cats and the 6 dogs.',
'The 3 pigs and the 2 sheep.',
'',
'#story fin #cats and dogs fin #sheep fin',
'blah yada',
'#sharkfin soup fin #fish fingers fin',
'9 fleas, 87 ticks, 654 lice.',
'42 cats #some sheep fin and 1 dog',
);
;;
for my $line (@lines) {
printf qq{'$line' -> };
;;
my $parsed =
my @extracted =
$line =~ m{ (?| (\d+) | \x23 (.*?) \s+ fin \b) }xmsg;
;;
print $parsed ? map qq{'$_' }, @extracted : 'nothing parsed';
}
"
'The 2 cats and the dog.' -> '2'
'The 8 cats and the 6 dogs.' -> '8' '6'
'The 3 pigs and the 2 sheep.' -> '3' '2'
'' -> nothing parsed
'#story fin #cats and dogs fin #sheep fin' -> 'story' 'cats and dogs'
+'sheep'
'blah yada' -> nothing parsed
'#sharkfin soup fin #fish fingers fin' -> 'sharkfin soup' 'fish finger
+s'
'9 fleas, 87 ticks, 654 lice.' -> '9' '87' '654'
'42 cats #some sheep fin and 1 dog' -> '42' 'some sheep' '1'
Give a man a fish: <%-{-{-{-<