Расширение и сжатие табуляций

Задача
Нужно заменить пробелы на табуляцию (или табуляцию на пробелы) и в то же время сохранить выравнивание теста по позициям табуляции. Например, вы хотите отобразить для пользователя текст стандартным образом.

Решение
Для замены пробелов на табуляцию или табуляции на пробелы следует применять функцию str_replace():

$r = mysql_query("SELECT message FROM messages WHERE id = 1") or die();
$ob = mysql_fetch_object($r);
$tabbed = str_replace(' ',"\t",$ob->message);
$spaced = str_replace("\t",' ',$ob->message);
print "With Tabs:
$tabbed
";
print "With Spaces:
$spaced
";

Однако если для преобразования применяется функция str_replace(), то позиции табуляции нарушаются. Если вы хотите ставить табуляцию через каждые восемь символов, то в строке, начинающейся с пятибуквенного слова и табуляции, необходимо заменить табуляцию на три пробела, а не на один. Для замены табуляции на пробелы с учетом
позиций табуляции следует применять функцию pc_tab_expand(), показанную в примере 1.1.

Пример 1.1. pc_tab_expand()
function pc_tab_expand($a) {
$tab_stop = 8;
while (strstr($a,"\t")) {
$a = preg_replace('/^([^\t]*)(\t+)/e',
"'\\1'.str_repeat(' ',strlen('\\2') *
$tab_stop - strlen('\\1') % $tab_stop)",$a);
}
return $a;
}
$spaced = pc_tab_expand($ob->message);

Для обратной замены пробелов на табуляцию можно воспользоваться функцией pc_tab_unexpand(), показанной в примере 1.2.

Пример 1.2.


pc_tab_unexpand()
function pc_tab_unexpand($x) {
$tab_stop = 8;
$lines = explode("\n",$x);
for ($i = 0, $j = count($lines); $i < $j; $i++) {
$lines[$i] = pc_tab_expand($lines[$i]);
$e = preg_split("/(.\{$tab_stop})/",$lines[$i],-
1,PREG_SPLIT_DELIM_CAPTURE);
$lastbit = array_pop($e);
if (!isset($lastbit)) { $lastbit = ''; }
if ($lastbit == str_repeat(' ',$tab_stop)) { $lastbit = "\t"; }
for ($m = 0, $n = count($e); $m < $n; $m++) {
$e[$m] = preg_replace('/ +$',"\t",$e[$m]);
}
$lines[$i] = join('',$e).$lastbit;
}
$x = join("\n", $lines);
return $x;
}
$tabbed = pc_tab_unexpand($ob->message);

Обе функции принимают в качестве аргумента строку и возвращают ее, модифицировав соответствующим образом.

Обсуждение
Каждая функция предполагает наличие позиций табуляции через каждые восемь пробелов, но это можно изменить, задав переменную $tab_stop. Регулярное выражение в pc_tab_expand() соответствует и группе табуляций, и всему тексту в строке перед группой табуляций. Оно должно соответствовать тексту перед табуляциями, поскольку от длины этого текста зависит количество пробелов, замещающих табуляции, а последующий текст должен быть выровнен по позиции следующей табуляции.


Эта функция не просто заменяет каждую табуляцию на восемь пробелов; она выравнивает текст, стоящий после табуляции, по позициям табуляций.

Точно так же функция pc_tab_unexpand() не только ищет восемь последовательных пробелов, а затем заменяет их одним символом табуляции. Она делит каждую строку на участки по восемь символов, а затем замещает пробелы в конце этих участков (по крайней мере два пробела) на табуляции. Это не только сохраняет выравнивание текста по позициям табуляций, но и сохраняет пробелы в строке.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Анализ данных, разделенных запятой
Анализ данных, состоящих из полей фиксированной ширины
Включение функций и выражений в строки
Доступ к подстрокам
Замещение подстрок

Вернуться в раздел: PHP / 1. Строки