PHP - удалить перенос строки в ячейке CSV

Многие разработчики часто сталкиваются с проблемой импорта CSV-файлов, а именно с тем, что в исходном файле в ячейке содержатся переносы строк.

Такой файл невозможно корректно прочитать в php - все функции перенос в ячейке упорно считают окончанием строки. Из-за этого структура данных нарушается и импорт становится невозможным.

Исходный файл

Для того, чтобы все работало, текстовые поля должны быть обрамлены в двойные ковычки. Это стандартная схема для csv файла.

// строки в файле
"элемент 1";"текст 
с переносом";"элемент 2"
"элемент 12";"текст 
с переносом";"элемент 22"

Удаляем перносы

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

// функция, которая просто удаляет переносы и табуляторы
function delete_rn($matches = array())
{
  if(isset($matches[1])) {
    return str_replace(array("\r\n", "\r", "\n", "\t"), ' ', $matches[1]);
  } else {
    return $matches[0];
  }
}

// путь к исходному файлу
$filePath = 'my_file.csv';

// считываем файл
$fileContent = file_get_contents($filePath);

// стандартное экранирование кавычек в тексте надо пока убрать, чтобы не было путаницы в кавычках
$fileContent = str_replace('""', '__ECR__', $fileContent);

// теперь воспользуемся функцией preg_replace_callback и вызовем нашу функцию удаления переносов
$pattern = '/("[^"]*")|[^"]*/i';
$result = preg_replace_callback($pattern, "delete_rn", $fileContent);

// вернем обратно экранированные кавычки
$result = str_replace('__ECR__', '""', $result);

// теперь запишем наш результат в новый файл
$fileOutPath = 'my_csv_new.csv';
file_put_contents($fileOutPath, $result);

// на выходе мы получим такой результат (все переносы, обрамленные кавычками удалены)
"элемент 1";"текст с переносом";"элемент 2"
"элемент 12";"текст с переносом";"элемент 22"

Вот такой несложный способ избавит вас от проблем с переносами в тестовых полях CSV-файла.

Комментарии