Expanding and Compressing Tabs
Problem
You want to convert tabs in a string to the appropriate number of spaces, or vice versa. Converting spaces into tabs can be used to reduce file size when the file has many consecutive spaces. Converting tabs into spaces may be required when producing output for devices that don’t understand tabs or think they’re at different positions than you do.
Solution
Either use a rather funny looking substitution:
while ($string =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {
# spin in empty loop until substitution finally fails
}Or the standard Text::Tabs module:
use Text::Tabs; @expanded_lines = expand(@lines_with_tabs); @tabulated_lines = unexpand(@lines_without_tabs);
Discussion
Assuming that tab stops are set every N
positions (where N is customarily eight),
it’s easy to convert them into spaces. The standard, textbook
method does not use the Text::Tabs module but suffers from being
difficult to understand. Also, it uses the
$` variable, whose very mention currently
slows down every pattern match in the program. The reason for this is
given in Section 6.0.3 in Chapter 6.
while (<>) {
1 while s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e;
print;
}If you’re looking at the second while loop
and wondering why it couldn’t have been written as part of a
simple s///g instead, it’s because you need
to recalculate the length from the start of the line again each time
(stored in $`) rather than merely from where
the last match occurred.
The obscure convention ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access