[英]PHP cannot parse CSV correctly (file is in UTF-16LE)
我正在尝试使用PHP解析CSV文件。
该文件使用逗号作为定界符,并对包含逗号的字段使用双引号 ,例如:
foo,"bar, baz",foo2
我面临的问题是我将包含逗号的字段分隔开了。 我得到:
"2
rue du ..."
代替: 2, rue du ...
编码方式:
该文件似乎不在UTF8中。 它在开始时具有怪异的特征( 显然不是BOM ,当从ASCII转换为UTF8: ÿþ
时看起来像这样),并且不显示任何重音符号。
mb_detect_encoding()
返回ASCII码 但是它无法转换:
mb_convert_encoding()
从ASCII
转换,但从UTF-16LE
返回亚洲字符 iconv()
返回注意:iconv():错误的字符集,不允许从UTF-16LE
/ ASCII
转换为UTF8
。 解析:
我试图使用str_getcsv()
来解析这种单行代码(请参阅这2条评论 str_getcsv()
:
$csv = array_map('str_getcsv', file($file['tmp_name']));
然后,我尝试使用fgetcsv()
:
$f = fopen($file['tmp_name'], 'r');
while (($l = fgetcsv($f)) !== false) {
$arr[] = $l;
}
$f = fclose($f);
通过两种方式,我将获得2个部分的地址字段。 但是当我尝试此代码示例时,我得到了正确解析的字段:
$str = 'foo,"bar, baz",foo2,azerty,"ban, bal",doe';
$data = str_getcsv($str);
echo '<pre>' . print_r($data, true) . '</pre>';
总结问题:
UTF-16 LE
读取文件,并且开头不显示奇怪的字符) 我终于自己解决了:
我将该文件发送到了返回UTF16LE的在线编码检测网站。 在检查了什么是UTF16LE之后,它说它具有BOM(字节顺序标记) 。
我以前的尝试是使用file()
返回文件行的数组,以及使用fopen()
返回资源,但是我们仍然逐行解析。
我想到的工作解决方案是转换整个文件(一次一行),而不是分别转换每一行。 这是一个可行的解决方案:
$f = file_get_contents($file['tmp_name']); // Get the whole file as string
$f = mb_convert_encoding($f, 'UTF8', 'UTF-16LE'); // Convert the file to UTF8
$f = preg_split("/\R/", $f); // Split it by line breaks
$f = array_map('str_getcsv', $f); // Parse lines as CSV data
我不再在内部逗号之间分开地址字段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.