use v5.12.0;
use warnings;
s/\A(?:[0369]|[147][0369]*(?:[147][0369]*[258][0369]*)*(?:[147][0369]*[147]|[258])|[258][0369]*(?:[258][0369]*[147][0369]*)*(?:[258][0369]*[258]|[147]))*(?:0|[147][0369]*(?:[147][0369]*[258][0369]*)*5|[258][0369]*(?:[258][0369]*[147][0369]*)*[258][0369]*5)\z/Fizzbuzz/,
s/\A(?:[0369]|[147][0369]*(?:[147][0369]*[258][0369]*)*(?:[147][0369]*[147]|[258])|[258][0369]*(?:[258][0369]*[147][0369]*)*(?:[258][0369]*[258]|[147]))+\z/Fizz/,
s/\A[0-9]*[05]\z/Buzz/,
say
for 1 .. 100
This can also be written as a recursive pattern but I didn’t have sufficient chops×persistence to puzzle it out.
use v5.14; say s{ ^ (?<a> [0369]* (*PRUNE) ) (?: (?<b> [147] (*PRUNE) ) (?<B> (?&a) (?: (?&c) | (?&b) (?&C) ) ) | (?<c> [258] (*PRUNE) ) (?<C> (?&a) (?: (?&b) | (?&c) (?&B) ) ) )* (?&a) (?<=(\d)) $ }{Fizz$+}rx =~ s/\d*[05]$/Buzz/r =~ s/\D\K\d+//r for 1..100;Actually that had a bug on 5-digit numbers and it turns out the regex engine doesn't need backtracking control here either.