in reply to ignoring empty returns from split

This is possible to solve using map. map removes list the element in question if an empty list is returned: @after = map { (length) ? $_ : () } @before; FYI, you can also return lists to insert entries. From perlfunc under map:
Evaluates BLOCK or EXPR in list context, so each element of LIST may p +roduce zero, one, or more elements in the returned value.
However, grep is more suitable for this purpose. It's also faster:
use Benchmark; @b = (1, 2, 3, undef, 4, 5, undef, 5, 6, 7, undef, 8, undef, 9, 0, 0, 0, 0, 1, 3, 4, undef, undef, undef, 9); timethese(50_000, { 'map' => sub { my (@a); @a = map { (length) ? $_ : () } @b; }, 'grep'=> sub { my (@a); @a = grep { length } @b; } }); Benchmark: timing 50000 iterations of grep, map... grep: 6 wallclock secs ( 6.48 usr + 0.00 sys = 6.48 CPU) @ 77 +16.05/s (n =50000) map: 10 wallclock secs ( 9.28 usr + 0.00 sys = 9.28 CPU) @ 53 +87.93/s (n =50000)