Починка JSON
Починить JSON: убираются комментарии и висячие запятые, кавычки правятся, переносы строк экранируются. Список всех исправлений и проверка результата.
Когда нужно починить JSON
Битый JSON появляется по предсказуемым причинам, и почти всегда это не ошибка программиста, а следствие ручной правки. Файл правили руками в редакторе, скопировали кусок из документации, вырезали из лога, выгрузили из инструмента, который пишет почти-JSON. Потом вставили в конфигурацию, и в ответ прилетело сообщение об ошибке разбора. Починить json в таком случае — значит сделать работу, которую и так делает человек: убрать комментарии, поправить кавычки, снять запятую, которую забыли стереть, и закрыть скобку, которая не закрылась. Разница в том, что человек делает это вручную и не всегда понимает, что именно он изменил, а здесь каждое исправление видно отдельной строкой: было и стало.
Что умеет починка
- Убираются комментарии в стиле // и блоки /* */, не задевая содержимое строк
- Одинарные кавычки заменяются на двойные с сохранением экранирования
- Удаляются висячие запятые перед закрывающей скобкой и квадратной скобкой
- Управляющие символы и переводы строк внутри строк экранируются
- Ключи, записанные без кавычек, получают кавычки
- Незакрытые скобки и кавычки закрываются, а результат проверяется через JSON.parse
Как починить файл
- Вставьте содержимое файла в поле ввода
- Нажмите «Починить» — исправления пойдут в фиксированном порядке
- Посмотрите список изменений: там видно, что было и что стало
- Скопируйте результат, если проверка JSON.parse прошла
- Если не прошла, посмотрите указанную позицию и поправьте файл вручную
Как устроена починка
Разбор битого текста идёт в шесть проходов, и порядок проходов важен. Сначала удаляются комментарии: пока они на месте, двоеточие или фигурная скобка внутри комментария выглядят как структура. Затем одинарные кавычки переводятся в двойные, причём содержимое строки сохраняется, а экранированные символы пересчитываются. Третий проход снимает висячие запятые: сканирование идёт посимвольно, строки отслеживаются отдельно, и запятая удаляется только тогда, когда следом за ней, пропустив пробелы, идёт закрывающая скобка. Четвёртый проход экранирует переводы строк и другие управляющие символы внутри строк. Пятый одевает в кавычки ключи, записанные без них. Шестой закрывает незакрытые строки и скобки. В конце результат один раз проверяется через JSON.parse, и только после этого он считается готовым.
Что происходит с типичными поломками
| Было | Что сделано | Стало |
|---|---|---|
| { "a": 1, } | убрана висячая запятая перед закрывающей скобкой | { "a": 1 } |
| { 'name': 'Alice' } | одинарные кавычки заменены на двойные | { "name": "Alice" } |
| { // заметка "a": 1 } | удалён комментарий | { "a": 1 } |
| { /* блок */ "a": 1 } | удалён блок комментария | { "a": 1 } |
| {name: "Alice"} | ключ одет в кавычки | {"name": "Alice"} |
| {"a": 1, "b": [1, 2" | закрыты квадратная и фигурная скобки | {"a": 1, "b": [1, 2]} |
| {"text": "строка вторая"} | перевод строки внутри строки экранирован | {"text": "строка\nвторая"} |
| {"url": "http://x/a//b"} | двойной слеш внутри строки оставлен как есть | {"url": "http://x/a//b"} |
| {"a": 1 "b": 2} | нечего чинить, показана позиция ошибки | разбор останавливается на позиции 8 |
| [1, 2, 3,] | убрана запятая в конце массива | [1, 2, 3] |
| {'a': 'it\'s'} | экранированная кавычка сохранена | {"a": "it's"} |
| {"note": "/* не комментарий */"} | содержимое строки не тронуто | {"note": "/* не комментарий */"} |
Каждая строка показывает, что именно изменилось. Ошибки на местах починки не исправляются, а показываются.
Откуда берётся битый JSON
Первый источник — правка руками. Конфигурацию дописывают в редакторе, где подсветки нет, и по привычке ставят комментарий или забывают запятую. Второй источник — копирование примеров из документации: в примере почти всегда есть комментарий или одинарные кавычки для наглядности, а в конфигурации это уже не работает. Третий — инструменты, которые пишут почти-JSON: выгрузка логов, экспорт из редактора конфигураций, генерация тестовых данных.
Четвёртый источник — объединение файлов. Два куска склеили, и на стыке осталась запятая без пары или не хватило запятой между объектами. Пятый — редактор, который сохранил файл с переносом строки внутри значения, например при переносе длинного текста. Шестой — вырезанный из лога фрагмент: его скопировали из сообщения об ошибке, и структура оказалась неполной. Практически во всех случаях починка справляется, а вот когда файл обрезан посередине значения, она честно скажет, что разбор останавливается, и покажет позицию.
- Ручная правка конфигурации в редакторе без подсветки
- Копирование примера из документации, где есть комментарии
- Выгрузка из инструмента, пишущего почти-JSON
- Склейка двух кусков файла на стыке
- Перенос длинного текста с новой строки внутри значения
- Фрагмент лога, вырезанный из сообщения об ошибке
Что JSON не прощает и почему
Строгий формат не терпит почти ничего лишнего. Комментарий в разных реализациях понимают по-разному, поэтому в стандарте его нет. Одинарные кавычки допустимы в некоторых языках, но не в JSON. Запятая перед закрывающей скобкой выглядит естественно, но означает «после этого элемента идёт ещё один», а элемента нет. Перевод строки внутри строки запрещён буквально: строка в JSON не может содержать неэкранированную управляющую последовательность. Ключ без кавычек — привычная запись в JavaScript и Python, но не в JSON.
Именно поэтому разбор JSON останавливается на первом нарушении и не идёт дальше: чтобы понять структуру, надо разобрать предыдущую. Отсюда и ценность позиции в сообщении об ошибке: она указывает первое проблемное место, а не последнее. Разница между ошибкой синтаксиса и ошибкой в данных тоже важна: первая означает, что файл не прочитан вообще, вторая — что прочитан, но значение неожиданное. Починка работает только с первой категорией, и это честное ограничение.
- Комментарии в JSON не предусмотрены стандартом
- Только двойные кавычки, одинарные не считаются строкой
- Запятая перед закрывающей скобкой означает отсутствующий элемент
- Перевод строки внутри строки нужно экранировать
- Ключ без кавычек допустим в других языках, но не в JSON
- Разбор останавливается на первом нарушении, а не на последнем
Разбор примера по шагам
Возьмём файл, в котором намешано сразу несколько поломок: комментарий в начале, одинарные кавычки у ключа и значения, висячая запятая в конце и незакрытая скобка. Первый проход убирает комментарий, но смотрит при этом на кавычки: если бы в строке было значение с // внутри кавычек, такой текст остался бы на месте, потому что это данные, а не комментарий. Второй проход переводит четыре одинарные кавычки в двойные и следит за экранированием.
Третий проход идёт по всему тексту и смотрит, что стоит за запятой: если после запятой, пропустив пробелы, идёт закрывающая скобка, запятая лишняя и удаляется. Четвёртый проход закрывает незакрытую строку и добавляет недостающие скобки в обратном порядке. После этого результат один раз прогоняется через JSON.parse: если разбор прошёл, значит файл теперь читается любым стандартным парсером. Если нет, инструмент показывает сообщение разбора, позицию и фрагмент текста рядом с проблемным местом.
Что происходит на каждом проходе
| Проход | Действие | Результат |
|---|---|---|
| 1 | Удаление комментариев | // до конца строки и /* */ целиком |
| 2 | Замена кавычек | Одинарные на двойные, содержимое сохраняется |
| 3 | Висячие запятые | Запятая перед } или ] удаляется |
| 4 | Управляющие символы | Перевод строки и таб внутри строки экранируются |
| 5 | Ключи без кавычек | Ключ получает кавычки |
| 6 | Незакрытые конструкции | Строка и скобки закрываются |
| 7 | Проверка | JSON.parse на результате |
| 8 | Список изменений | Что было и что стало по каждому правлению |
Каждый проход работает с текстом целиком, но порядок между ними принципиален: сначала убирается то, что мешает увидеть структуру.
С чем починка работает рядом
Починка и форматирование решают разные задачи, и порядок обычно такой: сначала починить, потом отформатировать. Пока файл не читается, отступы и переносы строк в нём не имеют значения, а вот как только файл стал валидным, его можно привести к читаемому виду. Дальше по цепочке может стоять проверка JSON Schema, если схема есть, и поиск по JSONPath, если нужно достать конкретное значение. Для сравнения двух версий пригодятся сравнение JSON и разница текстов — они особенно полезны, когда один из файлов пришлось починить.
Отдельный сюжет — выгрузки. Часто JSON приходит из внешнего источника, и задача не починить файл, а разобрать его содержимое: конвертер CSV в JSON показывает таблицу, конвертер JSON в CSV выгружает обратно, а генератор типов TypeScript превращает структуру в интерфейсы для кода. И ещё одно: минификатор приводит JSON к компактному виду, когда размер файла важен, например при отправке по сети.
- Сначала починка, потом форматирование
- Пока файл не читается, его вид не имеет значения
- Проверка по схеме идёт после того, как файл разобран
- Сравнение версий полезно после починки обеих
- Выгрузки и таблицы требуют уже других инструментов
- Компактный вид важен, когда файл уходит по сети
Частые вопросы
Какие ошибки JSON починить можно
Что значит ошибка синтаксиса JSON и как её найти
Почему JSON не допускает комментариев
Что будет с типами данных при починке
Безопасно ли отдавать такой файл в продакшен
Что делать, если починить не удалось
Чем отличается починка от форматирования JSON
Можно ли восстановить потерянные данные
Похожие инструменты
Форматирование и валидация JSON
Форматирование, украшение, валидация и минификация JSON с древовидным просмотром
Форматирование XML
Форматирование, украшение, минификация и валидация XML документов
Конвертер CSV в JSON
Конвертация данных CSV в формат массива JSON с настраиваемыми разделителями
JSON в TypeScript
Сгенерируйте TypeScript-интерфейсы из любого JSON — с вложенными объектами и массивами.
Конвертер JSON в CSV
Конвертация массива JSON в формат CSV с автоопределением столбцов
Конвертер JSON в YAML
Конвертация данных JSON в формат YAML с правильными отступами
Конвертер YAML в JSON
Конвертация данных YAML в формат JSON с поддержкой вложенных структур
Конвертер Markdown в HTML
Конвертация Markdown в HTML с поддержкой предпросмотра