Есть ли обходные пути для ошибки PHP fgetcsv, при которой пробелы обрезаются?

#php #csv

#php #csv

Вопрос:

Учитывая следующую строку данных CSV (я не могу убедиться, что поля заключены в кавычки)

 AB,CD,   EF,GH,   IJ
  

и PHP-код для:

 $arr = fgetcsv($f);
  

(предполагая, что $ f является допустимым указателем на файл, считывающим файл, содержащий приведенный выше текст) — можно было бы ожидать такого результата:

 Array('AB', 'CD', '   EF', 'GH', '   IJ');
  

когда на самом деле вы получаете:

 Array('AB', 'CD', 'EF', 'GH', 'IJ');
  

Это проблематично, если вам нужен позиционный контекст в этом поле.

Какие-либо обходные пути, позволяющие по-прежнему использовать преимущества fgetcsv, но гарантирующие, что пробелы не будут потеряны?

Сообщение об ошибке приведено здесь: http://bugs.php.net/bug.php?id=53848

Комментарии:

1. Для меня это новость. Поведение PHP в значительной степени соответствует моим ожиданиям. В любом случае, вы можете просто использовать explode(",", $line) , поскольку это на самом деле то, что вы хотите.

2. @mario: Но это работает не во всех случаях.

3. @mario: Я хочу воспользоваться преимуществами fgetcsv, когда это возможно, особенно с полями в кавычках, если они доступны.

4. Вы не сможете воспользоваться fgetcsv, если он не выполняет то, что вы хотите. Я мог бы написать вам регулярное выражение для цитирования полей без кавычек. Но было бы разумнее просто использовать указанную вещь для извлечения.

5. Этот парень опубликовал обходной путь здесь: thuejk.blogspot.com Я еще не тестировал.

Ответ №1:

Оооопс. Дерьмо.
Я случайно уже написал функцию, которая не удаляет пробелы:

 function str_getcsv2($line, $del=",", $q='"', $esc="\") {
    $line = rtrim($line, "rn");
    preg_match_all("/G ([^$q$del]*) $del | $q(( [$esc$esc][$q]|[^$q]* ) )$q $del /xms", "$line,", $r);
    foreach ($r[1] as $i=>$v) {  // merge both captures
        if (empty($v) amp;amp; strlen($r[2][$i])) {
            $r[1][$i] = str_replace("$esc$q", "$q", $r[2][$i]);  // remove escape character
        }
    }
    return($r[1]);
}
  

Используйте это как:

 $arr = str_getcsv2(fgets($f));