Как правильно избежать двойных кавычек в строках, вложенных в объект JSON, расположенный в столбце CSV?

У меня есть вариант использования, когда клиенту необходимо загрузить объекты, сериализованные в формате JSON, через импорт CSV. Некоторые из этих объектов содержат строки, содержащие двойные кавычки. Обычно я просто добавляю '\' перед вложенными двойными кавычками, чтобы избежать их, однако это, похоже, противоречит синтаксическому анализу файла CSV. Мы используем PHP 7.0 и функцию «fgetcsv» для чтения строк файла. Каждый раз, когда я это делаю, я замечаю странное поведение после того, как встречается экранированная двойная кавычка. Вот пример строки из CSV:

"{""test"": ""\""this\"" is a test""}"

А вот как PHP читает этот столбец с помощью fgetcsv:

{"test": "\"this\"" is a test""}"

Я подтвердил наличие двойных кавычек после того, как начальная экранированная двойная кавычка столкнулась с этой проблемой. Думая, что обратная косая черта может вызывать проблемы с экранированием, я попытался использовать другую обратную косую черту, чтобы избежать обратной косой черты:

"{""test"": ""\\""this\\"" is a test""}"

И вот результат:

{"test": "\\"this\\" is a test"}

Таким образом, хотя это действительно решает проблему с любыми двойными кавычками за пределами первой, у меня остается две обратные косые черты вместо одной.

Есть ли способ избежать этих данных, не изменяя базовый код, чтобы fgetcsv правильно их интерпретировал? Вот так:

{"test": "\"this\" is a test"}

Вам нужно, чтобы эти CSV были прочитаны кем-либо, кроме fgetcsv?

Nathan Hinchey 22.08.2018 22:32

@NathanHinchey Я не могу придумать другого варианта использования, так что мы можем ограничить область действия fgetcsv.

ryanmovista 22.08.2018 22:34

Вы можете уточнить, какой желаемый результат? Это {"test": "\"this\" is a test"}? (Чтобы оцененное значение "this" в JSON было "this" is a test)

Nathan Hinchey 22.08.2018 22:35

@NathanHinchey Точно. Я тоже добавил это к вопросу для ясности.

ryanmovista 22.08.2018 22:38

@NathanHinchey Это на самом деле в выводе, а не опечатка

ryanmovista 22.08.2018 22:47

Конкретно в этом выводе я имел в виду: {"test": "\"this\"" is a test""}"; " после фигурной скобки - это опечатка?

Nathan Hinchey 22.08.2018 22:54

@NathanHinchey, это не опечатка. Эта двойная кавычка присутствует в выводе.

ryanmovista 22.08.2018 22:59

Это странно.

Nathan Hinchey 22.08.2018 23:04
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
8
1 022
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете попробовать использовать \" для представления двойных кавычек вместо "".

Например, "{\"test\": \"\\\"this\\\" is a test\"}"

Работает ли это, может зависеть от версии fgetcsv, которую вы используете - я не уверен.


В качестве альтернативы, если вы используете fgetcsv 5.3 или более позднюю версию, вы можете попробовать изменить параметры fgetcsv, чтобы изменить символ вложения или escape-символ, чтобы он не конфликтовал с JSON. См. Параметры в документы fgetcsv.

enclosure

The optional enclosure parameter sets the field enclosure character (one character only).

escape

The optional escape parameter sets the escape character (one character only).

Note: Usually an enclosure character is escaped inside a field by doubling it; however, the escape character can be used as an alternative. So for the default parameter values "" and \" have the same meaning. Other than allowing to escape the enclosure character the escape character has no special meaning; it isn't even meant to escape itself.

(курсив в оригинале)

Я видел параметр escape-символа в документации fgetcsv, однако в идеале решение потребовало бы изменения только самого файла CSV, а не базового кода. Это может быть невозможно, но если да, то это, безусловно, предпочтительное решение.

ryanmovista 22.08.2018 22:41

{\ "test \": \ "\\\" this \\\ "is a test \"} тоже не был правильно проанализирован. Он был проанализирован в точности так, как был введен: {\ "test \": \ "\\\" this \\\ "is a test \"}. Я использую PHP 7.0.

ryanmovista 22.08.2018 22:56

Вы заключили это в двойные кавычки? Если так, это СУПЕР странно, и я бы посоветовал регистрируя это как ошибку PHP, прикусить пулю и изменить свой код. Извините ¯ \ _ (ツ) _ / ¯

Nathan Hinchey 22.08.2018 23:03

Да. Действительно, очень странно. Спасибо за рекомендации.

ryanmovista 22.08.2018 23:05

Другие вопросы по теме