Я пытаюсь проанализировать файл CSV с помощью PHP.
Файл использует запятые как разделитель а также двойные кавычки для полей, содержащих запятую (и), как:
foo,"bar, baz",foo2
Проблема Я сталкиваюсь с тем, что я получаю поля, содержащие запятую (ы) разделены. Я получил:
"2
rue du ..."
Вместо: 2, rue du ...
,
Кодирование:
Файл, кажется, не в UTF8. В начале странные чудовища (видимо не спецификация, выглядит так при преобразовании из ASCII в UTF8: ÿþ
) и не отображает акценты.
mb_detect_encoding()
на линиях CSV возвращает ASCIIНо он не может преобразовать:
mb_convert_encoding()
преобразует из ASCII
но возвращает азиатские символы из UTF-16LE
iconv()
возвращается Примечание: iconv (): неправильная кодировка, преобразование из UTF-16LE
/ASCII
в UTF8
не допускается.Синтаксический:
Я пытался разобраться с этим однострочником (см. эти 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
Я больше не разделяю поля адреса на внутренние запятые.
Других решений пока нет …