3

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

我所做的是使用 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空间的制表符。

4

3 回答 3

6

我前段时间写过这个函数,可能会有所帮助:

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_,它会加速这个功能。

[+] Note that this is meant to work with one line, so you will need to process line by line with fgets instead of whole file at once.

于 2013-01-13T22:03:08.630 回答
1

您可以尝试使用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 也可以使用相同的技巧)

于 2013-01-13T21:29:15.073 回答
0

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

$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|) 执行任何操作。

这应该工作!

于 2013-01-13T21:46:51.950 回答