Расширение и сжатие табуляций
Решение
Для замены пробелов на табуляцию или табуляции на пробелы следует применять функцию 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: <pre>$tabbed</pre>
print "With Spaces: <pre>$spaced</pre>";
Однако если для преобразования применяется функция str_replace(), то позиции табуляции нарушаются. Если вы хотите ставить табуляцию через каждые восемь символов, то в строке, начинающейся с пятибуквенного слова и табуляции, необходимо заменить табуляцию на три пробела, а не на один. Для замены табуляции на пробелы с учетом позиций табуляции следует применять функцию pc_tab_expand(), показанную в примере:
Пример: 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(), показанной в примере:
Пример: 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() не только ищет восемь последовательных пробелов, а затем заменяет их одним символом табуляции. Она делит каждую строку на участки по восемь символов, а затем замещает пробелы в конце этих участков (по крайней мере два пробела) на табуляции. Это не только сохраняет выравнивание текста по позициям табуляций, но и сохраняет пробелы в строке.
Комментарии:
Комментариев нет
|
|
|