split looks like a better choice than a regex. I whittled away at this and came up with the untested:
for (split(/:/, $$pattern)) {
# make sure it starts and ends with spaces
$_ = 'S0' . $_ unless /^S/;
$_ .= 'S0' unless /S\d+$/;
my @pieces = split(/[SF](\d+)/, $_);
while (my ($spaces, $fills) = splice(@pieces, 0, 2)) {
$out .= " " x $spaces .
substr($camel, $camelcount, $fills);
}
$out .= "\n";
}
I'm fairly pleased with that, but might try to fit a
pack in there. (How would you have used
map?)
Aside, this:
while (/(.)/g) {
$camel .= $1 if $1 ne " ";
}
could be spelled:
tr/ //d;
$camel .= $_;
I'm sure you can trim that down more, too. Don't forget to check out
Acme::EyeDrops for a different take on things.
Update, very shortly after: You could, of course, just split on [SF] and probably get the same effect, though you'll have an empty element at the start. It may or may not be more clear that way.