使用PHP将选项卡转换为用于HTML显示的空格?
我需要显示一个纯文本文件,该文件在网页中包含两列空格制表符数据 我所做的是使用PHP读取文本文件并在使用PHP将选项卡转换为用于HTML显示的空格?,php,html,whitespace,Php,Html,Whitespace,我需要显示一个纯文本文件,该文件在网页中包含两列空格制表符数据 我所做的是使用PHP读取文本文件并在 <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
<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>
| | 43| 43| 7| | |
| 12|128|128|128| | 53|
| 3| 3| 3| 3| | |
| | | 21| 21| 39| |
但是,通过盲目地用两个空格替换所有选项卡,我们得到了以下结果:
$fc=str_replace("\t", "", $fc);
$fc = str_replace(" ", "", $fc);
我试图找到一种(相当简单的)方法,将制表符转换为空格,同时考虑不占用全部n
空格的制表符。您可以尝试使用函数
这里有一个例子:
//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);
关于格式的一些信息
(供您参考,C也有同样的技巧)首先,去掉所有制表符和空格:
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;
}
然后应用这些替代品。这些循环是因为在第一次运行时,替换可能不会命中所有可能的情况:
由于您有三个空格列,因此无需对3位数字(|XXX |)执行任何操作
这应该管用 我不久前写过这个函数,可能会有帮助:
它是用来处理多字节字符串的,如果你只有数字,你可以去掉mb
,它会加速这个功能
[+]请注意,这意味着要使用一行,因此您需要使用fgets
逐行处理,而不是一次处理整个文件。不幸的是,我认为您需要第二次通过才能准确计算列的宽度什么是相当简单的?如果允许一些循环,这并不难做到。我在想,str\u pad
你能发布你的data.txt的内容吗?你可以通过preg\u replace\u callback
和printf
来达到这个效果,仔细阅读这两种方法。@MadaraUchiha,printf
是个好主意,但是回调会收到一系列匹配,换句话说,它将得到一个标签数组,后面没有非空白字符。我认为可能可以使用列分隔符进行解析(假设它们与本例中的情况类似)。当然,在这一点上,逐行处理文件可能比执行字符串替换更容易。但是您必须首先删除选项卡(例如使用$fc=str_replace(“\t”,”,$fc);
)。您可以尝试使用printf函数。:printf(“%d”,'37')代码>但如何提取值(供您参考,C也有同样的技巧)
告诉我我已经知道了<代码>;-)实际上,我已经想出了一个类似的解决方法。我使用的(较小的)代码如下所示,虽然它适合我当前的需要,但它是特定于这一特定格式的,必须手动更改其他列宽、分隔符、每个空格的制表符等,并且很快将变得不可行<代码>$fc=str\u replace(“\n\t\t”,”,$fc);$fc=str\u replace(“\t\t”、”、$fc);$fc=str_替换(“\t |“,”,$fc);$fc=str_replace(“\t”,”,$fc)代码>啊,我明白了。我不知道您会使用其他格式。[+]注意,这意味着要使用一行,因此您需要使用fgets逐行处理,而不是一次处理整个文件。
Ah,这就是为什么以双制表符开头的行(在第一行之后)短于一个空格的原因。没问题,修复起来非常简单:$lines=explode(“\n”,$fc);foreach($l行)打印(tab2space($l)。“\n”)代码>
//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);
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;
}