PHP: выравниваем текст по столбцам
Речь не идёт о задаче красивого форматирования программного кода отступами (code alignment). Её можно попытаться решить многочисленными плагинами для Notepad++, такими как Ident By Fold или мощный TextFX с собственным меню (правда, все они обычно не работают так, как тебе нужно).
Отметим также, что код на C++ можно подровнять в редакторе среды Visual Studio. Пройдите в верхнее меню Сервис, Параметры, откройте список Текстовый редактор - C/C++ - Табуляция и настройте отступы по блоку так, как вам удобно
Мы хотим более скромно решить задачу columns alignment, то есть, "раскидать" некие строки текста с разделителями (в формате CSV или подобном) по столбцам, ширина каждого из которых определяется максимальной шириной попадающего туда элемента. Например, если разделитель - это пробел, а данные - это
Привет, мир 2 столбца!
то получится один из трёх вариантов результата
Привет,|мир 2 |столбца! Привет,| мир 2|столбца! Привет,| мир 2 |столбца!
в зависимости то того, как мы хотим выравнивать текст внутри столбцов (символом '|' показан разделитель между столбцами).
В PHP эта задача, в общем, уже решена стандартной функцией str_pad, нам остаётся лишь обернуть её в небольшой класс ColumnAlinger
и снабдить его несколькими настройками:
- публичное свойство
$columns_dividor
- символ или строка, разделяющие столбцы в исходном тексте, по умолчанию - табуляция; - публичное свойство
$output_dividor
- символ или строка для разделения столбцов в строке-результате, по умолчанию - пробел; - публичное свойство
$skip_empty_dividors
определяет, пропускать ли пустые строки и столбцы в исходных данных, по умолчанию нет (false
); - публичный метод
set_align
позволяет установить выравнивание внутри столбцов, значения приватного свойства$align_type
, которые он может установить - те же, что у функцииstr_pad
(STR_PAD_RIGHT
- дополнять пробелами справа,STR_PAD_LEFT
- слева,STR_PAD_BOTH
- с обеих сторон, то есть, центрировать); - публичный метод
get
получает строку с исходным текстом, выполняет всю работу и возвращает строку-результат.
Ниже показаны код класса, примеры его использования и вывод, получившийся в браузере.
<?php class ColumnAlinger { public $columns_dividor, $output_dividor, $skip_empty_dividors; private $align_type; function __construct ($columns_dividor = "\t", $output_dividor = ' ') { $this->columns_dividor = $columns_dividor; $this->output_dividor = $output_dividor; $this->align_type = STR_PAD_RIGHT; $this->skip_empty_dividors = false; } public function set_align ($align_type) { if (in_array($align_type,array(STR_PAD_RIGHT,STR_PAD_LEFT,STR_PAD_BOTH))) $this->align_type = $align_type; else $this->align_type = STR_PAD_RIGHT; } public function get ($data) { $fieldsbyrow = array(); $lines = explode("\n", $data); foreach ($lines as $line) { if ($this->skip_empty_dividors) { $line = trim($line); if (empty($line)) continue; $line = preg_replace ("/(\s)(\s+)/","$1",$line); } $fieldsbyrow[] = explode ($this->columns_dividor, rtrim($line)); } $maxfields = max(array_map('count', $fieldsbyrow)); foreach (range(0, $maxfields-1) as $col) { $maxwidth = 0; foreach ($fieldsbyrow as $fields) $maxwidth = max($maxwidth, strlen($fields[$col])); foreach ($fieldsbyrow as &$fields) $fields[$col] = str_pad ($fields[$col], $maxwidth, ' ', $this->align_type); unset($fields); //очень классический баг PHP, см. http://bugs.php.net/29992 } $result = ''; foreach ($fieldsbyrow as $fields) $result .= implode ($this->output_dividor, $fields)."\n"; return $result; } } //Ниже - пример использования класса $text1 = 'Текст со словами, разделёнными Одним пробелом на столбцы, А если их мы сможем выровнять, То мы, конечно, молодцы!'; $aligner = new ColumnAlinger (' ','|'); echo '<pre>'.$aligner->get($text1).'</pre><hr>'; $aligner->set_align (STR_PAD_BOTH); echo '<pre>'.$aligner->get($text1).'</pre><hr>'; $aligner->columns_dividor = "\t"; $aligner->output_dividor = ' '; $aligner->set_align (STR_PAD_LEFT); $text2= "Заменим\tтабуляции\tпробелами и\tвыровняем\tтекст\tпо правым\tграницам\tстолбцов."; echo '<pre>'.$aligner->get($text2).'</pre><hr>'; $text3 = ' Теперь разделители лишние есть, Мы это флажком захотели учесть.'; $aligner->columns_dividor = " "; $aligner->output_dividor = '|'; $aligner->skip_empty_dividors = true; echo '<pre>'.$aligner->get($text3).'</pre>'; ?>
вывод этого скрипта (скриншот)
19.02.2017, 15:36 [5082 просмотра]