字符不是它们出现的

时间:2012-02-03 18:53:30

标签: php character-encoding

我正在处理科学仪器输出的文本文件。我没有关于如何生成文件的文档。但是我发现它充满了看不见但看起来不正常的隐形字符和字符。我将文件读入数组并尝试清理它。这是我的过程(仅显示文件的前4行)。

$datarr=file($_FILES['gcfile']['tmp_name'],FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
处理前

$ datarr

(注意BOM,EOL仍在那里,字符串的长度太大):

array(4) {
  [0]=>
  string(168) "ÿþC:\CHEM32\2\DATA\20120120 DA KLR\20120120 DA KLR 2012-01-20 09-55-35\P21K1000001.D
"
  [1]=>
  string(33) "tryptophan + DA
"
  [2]=>
  string(55) "Number of Peaks found    2
"
  [3]=>
  string(63) ""  1  ,  13.08 ,       36.29 "
"
}

处理

$datarr[0]=removeBOM($datarr[0]);//remove byte order mark at beginning of file

$options=array(FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_LOW);
$patterns=array('/\pC/','/\'/', '/\"/');

array_walk($datarr,function(&$v) use($options, $patterns){
    $v=filter_var($v,FILTER_SANITIZE_STRING, $options);
    $v=trim(preg_replace($patterns,'',$v));
});
处理后

(注意保留$ datarr上的双引号[3],字符串长度〜=可见长度,BOM消失)

array(4) {
  [0]=>
  string(82) "C:\CHEM32\2\DATA\20120120 DA KLR\20120120 DA KLR 2012-01-20 09-55-35\P21K1000001.D"
  [1]=>
  string(15) "tryptophan + DA"
  [2]=>
  string(26) "Number of Peaks found    2"
  [3]=>
  string(38) ""  1  ,  13.08 ,       36.29 ""

$ datarr [3]虽然有很大改进,但仍然有一个报告的长度大于它的可见长度,并且“标记没有被删除。如果我输出字符串为ascii数字:

$l=strlen($datarr[3]);
for($i=0;$i<$l;$i++){
    echo ord($datarr[3][$i]), ", ";
}
echo PHP_EOL;
$x= '"  1  ,  13.08 ,       36.29 "
';//copied from webpage output
$l=strlen($x);
for($i=0;$i<$l;$i++){
    echo ord($x[$i]), ", ";
}

这就是我得到的:

38, 35, 51, 52, 59, 32, 32, 49, 32, 32, 44, 32, 32, 49, 51, 46, 48, 56, 32, 44, 32, 32, 32, 32, 32, 32, 32, 51, 54, 46, 50, 57, 32, 38, 35, 51, 52, 59, //original string
34, 32, 32, 49, 32, 32, 44, 32, 32, 49, 51, 46, 48, 56, 32, 44, 32, 32, 32, 32, 32, 32, 32, 51, 54, 46, 50, 57, 32, 34, 10, 9, //pasted from browser string

我有什么,我该怎么办?

1 个答案:

答案 0 :(得分:2)

我想我觉得这里有什么问题。扭转输出:

$array1 = array(38, 35, 51, 52, 59, 32, 32, 49, 32, 32, 44, 32, 32, 49, 51, 46, 48, 56, 32, 44, 32, 32, 32, 32, 32, 32, 32, 51, 54, 46, 50, 57, 32, 38, 35, 51, 52, 59);
$array2 = array(34, 32, 32, 49, 32, 32, 44, 32, 32, 49, 51, 46, 48, 56, 32, 44, 32, 32, 32, 32, 32, 32, 32, 51, 54, 46, 50, 57, 32, 34, 10, 9);
foreach($array1 as $char){
    echo chr($char);
}
echo PHP_EOL;
foreach($array2 as $char){
    echo chr($char);
}

我们得到:

&#34;  1  ,  13.08 ,       36.29 &#34;
"  1  ,  13.08 ,       36.29 "

很明显,问题是双引号的编码(因此当我们期望string(38)时,string(30)长度。这源于你filter_var()电话。 FILTER_SANITIZE_STRING过滤器将对引号进行编码。如果要阻止这种情况发生,则需要将FILTER_FLAG_NO_ENCODE_QUOTES标志添加到选项列表中。这应该会阻止引号的编码,并留下预期的字符串:

$options=array(FILTER_FLAG_NO_ENCODE_QUOTES,FILTER_FLAG_STRIP_HIGH, FILTER_FLAG_STRIP_LOW);