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.
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);
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 1
while
CONDITION
is the same as while
(CONDITION)
{
}
, but shorter. Its origins date to when Perl ran
the first incredibly faster than the second. While the second is now
almost as fast, it remains convenient, and the habit has stuck.
The standard Text::Tabs module provides conversion functions to
convert both directions, exports a $tabstop
variable to control the number of spaces per tab, and does not incur
the performance hit because it uses $1
and
$2
rather than $&
and
$`
.
use Text::Tabs; $tabstop = 4; while (<>) { print expand($_) }
We can also use Text::Tabs to “unexpand” the tabs. This
example uses the default $tabstop
value of 8:
use Text::Tabs; while (<>) { print unexpand($_) }
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.