使用PHP将制表符转换为HTML显示的空格


Using PHP to convert tabs to spaces for HTML display?

我需要在网页中显示一个纯文本文件,该文件包含两个空格制表符的数据列。

我所做的是使用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):' ', '&nbsp;', $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) 

这里有一些关于格式的信息。

首先,去掉所有的制表符和空格:

$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);

由于您有三个空格列,因此无需为3位数(|XXX|)做任何操作。

这应该可以工作!