You might want to construct your regular expression that captures all of the parameters separately. If you're weary about typing in an expression so large, you can construct it as a string and use that to match.
With the right tinkering, you can get all of your elements out in a single array. Using $DIGIT references limits how much you can get with each pass, since only 1 through 9 are available and you have many more elements than that.
I'd do something like this instead:
my $regex = '^-'
.('(\S+)\s+'x18)
.'(.{40})'
.'(.{40})'
.'(.*)';
You should be able to use this as usual:
if (my @match = /$regex/o)
{
# ... Use $match[0] through $match[20]
}
Of course, if you're worried about speed, you'd spend some time with the
Benchmark library testing variations.