Расширение и сжатие символов табуляции
Проблема
Требуется преобразовать символы табуляции в строке в соответствующее количество пробелов, или наоборот.
Преобразование пробелов в табуляцию сокращает объем файлов, имеющих много смежных пробелов.
Преобразование символов табуляции в пробелы может понадобиться при выводе на устройства, которые
не понимают символов табуляции или считают, что они находятся в других позициях.
Решение
Примените подстановку весьма странного вида:
while ($string =~ s/\t+/' ' x (length($&) * 8 - length(S') % 8)/e) {
# Выполнять пустой цикл до тех пор.
# пока выполняется условие подстановки
}
Также можно воспользоваться стандартным модулем Text::Tabs:
use Text::Tabs;
@expanded_lines = expand(@lines_with_tabs);
@tabulated_lines = unexpand(@lines_without_tabs);
Комментарий
Если позиции табуляции следуют через каждые N символов (где N обычно равно 8), их несложно
преобразовать в пробелы. В стандартном, «книжном» методе не используется модуль Text::Tabs, однако
разобраться в нем непросто. Кроме того, в нем используется переменная $', одно упоминание которой
замедляет поиск по шаблону в программе.
while (<>) {
1 while s/\t+/' ' х (length($&) * 8 - length($') %8)/e;
print;
}
Вы смотрите на второй цикл while и не можете понять, почему его нельзя было включить в конструкцию
s///g ?
Потому что вам приходится каждый раз заново пересчитывать длину от начала строки (хранящуюся в $'), а не от последнего совпадения.
Загадочная конструкция 1 while CONDITION эквивалентна while (CONDITION) {}, но более компактна. Она появилась
в те дни, когда первая конструкция работала в Perl несравнимо быстрее второй. Хотя сейчас второй вариант
почти не уступает по скорости, первый стал удобным и привычным.
Стандартный модуль Text::Tabs содержит функции преобразований в обоих направлениях, экспортирует переменную
$tabstop, которая определяет число пробелок на символ табуляции. Кроме того, это не приводит к снижению
быстродействия, потому что вместо $& и $' используются $1 и $2:
use Text::Tabs;
$tabstop = 4;
while (<>) { print expand($_) }
Модуль Text::Tabs также может применяться для «сжатия» табуляции. В следующем примере используется
стандартное значение $tabstop, равное 8:
use Text::Tabs;
while (<>) { print unexpand($_) }
См. такжеОписание оператора s///
Proverte kod v komentariyah gde pro list tam oshibki detskie
Оставить комментарий:
|
|