I don't feel I clearly understand the problem ccelt09 is trying to address, but here's an approach (one of many) that might be helpful as a first approximation to a solution. Note: No validation of ranges is done to insure against negative start/end offsets, start/end inversion, overlap, etc.
>perl -wMstrict -le
"my $test = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
;;
my %inclusive_ranges = map { $_ => 1 } 7 .. 11, 18 .. 22;
;;
my @excluded = grep ! $inclusive_ranges{$_}, 0 .. length($test) - 1;
;;
my $str = $test;
print qq{'$str'};
;;
substr $str, $_, 1, '-' for @excluded;
print qq{'$str'};
"
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'-------HIJKL------STUVW---'
Update: Another way, same caveats. Note: This approach assumes the \x00 (null) character is never part of input data.
>perl -wMstrict -le
"my $test = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
;;
my %inclusive_ranges = map { $_ => 1 } 7 .. 11, 18 .. 22;
;;
my $exclude_mask =
join '',
map $inclusive_ranges{$_} ? qq{\xFF} : qq{\x00},
0 .. length($test) - 1
;
;;
my $str = $test;
print qq{'$str'};
;;
$str &= $exclude_mask;
$str =~ tr/\x00/-/;
print qq{'$str'};
"
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'-------HIJKL------STUVW---'