Мне нужно отобразить файл с открытым текстом, содержащий два-пробельные вкладки данных на веб-странице.
То, что я сделал, это использовать PHP для чтения текстового файла и распечатать его между тегами <pre>
чтобы использовать моноширинный шрифт так:
<pre> <?php $fn="data.txt"; $fi=fopen($fn, "r"); $fc=fread($fi, filesize($fn)); //open and read text file fclose($fi); $fc=str_replace("\t", " ", $fc); //replace tabs with two spaces print($fc); //print data between PRE tags ?> </pre>
Он почти работает, но вкладки становятся хлопотными. Тривиально заменять вкладки двумя пробелами, но затем символы без пробелов перевернуты, а не абсорбируются на вкладках. Истинные вкладки поглощают n-1
не-пробельные символы (где n
– количество пробелов на вкладку).
Например, следующая таблица должна отображаться так:
| | 43| 43| 7| | | | 12|128|128|128| | 53| | 3| 3| 3| 3| | | | | | 21| 21| 39| |
Однако, слепо заменив все вкладки двумя пробелами, мы получим следующее:
| | 43| 43| 7| | | | 12|128|128|128| | 53| | 3| 3| 3| 3| | | | | | 21| 21| 39| |
Я пытаюсь вычислить (достаточно простой) способ преобразования вкладок в пробелы при учете вкладок, которые не занимают полные n
пробелов.
Я написал эту функцию некоторое время назад, может быть полезно:
function tab2space($line, $tab = 4, $nbsp = FALSE) { while (($t = mb_strpos($line,"\t")) !== FALSE) { $preTab = $t?mb_substr($line, 0, $t):''; $line = $preTab . str_repeat($nbsp?chr(7):' ', $tab-(mb_strlen($preTab)%$tab)) . mb_substr($line, $t+1); } return $nbsp?str_replace($nbsp?chr(7):' ', ' ', $line):$line; }
Он предназначался для обработки многобайтовых строк, если у вас есть только номера, вы можете избавиться от mb_
, это ускорит эту функцию.
[+] Обратите внимание, что это предназначено для работы с одной строкой, поэтому вам нужно будет обрабатывать строки за строкой с помощью fgets
а не всего файла сразу.
Вы можете попробовать использовать функцию printf .
Вот пример:
printf("%4d",'37'); // will print ' 37' (with 2 spaces before 37) printf("%6d",'37'); // will print ' 37' (with 4 spaces before 37) printf("%6d",'337'); // will print ' 37' (with 3 spaces before 37)
Некоторая информация о формате здесь .
(Для вашей информации такой же трюк доступен с помощью C)
Во-первых, избавиться от всех вкладок и пробелов:
$fc=str_replace("\t", "", $fc); $fc = str_replace(" ", "", $fc);
Затем примените эти замены. Циклы состоят в том, что при первом запуске замена может не ударить все возможные случаи:
//deal with the case of two pipes next to each other while(strpos($fc, "||") !== false) $fc = str_replace("||", "| |", $fc); //deal with the case of |XX| while(preg_match('/\|[0-9][0-9]\|/', $fc) !== 0) $fc = preg_replace('/\|([0-9])([0-9])\|/', '| ${1}${2}|', $fc); //deal with the case of |X| while(preg_match('/\|([0-9])\|/', $fc) !== 0) $fc = preg_replace('/\|([0-9])\|/', '| ${1}|', $fc);
Поскольку у вас есть три пробела, не нужно ничего делать для трехзначных чисел (| XXX |).
Это должно сработать!