Поскольку доступный в сети парсер для меня оказался тяжеловат+ требовал встраивания в конфигурацию, я решил написать свою версию. Здесь представлен вариант работы с Таблицей Значений для наглядности, хотя мне удобнее работать с объектами XDTO. Для парсинга строки по итогам работы нам нужно знать только позицию и вес(длину) подстроки объкта, что позволяет легко и быстро организовать доступ к объекту, даже не зная его содержания. "Типобъекта" и "родитель" позволяют строить дерево объектов в xdto.
Сейчас работаю через парсер со smartsheet.api, ошибок пока не было, но в любом случае, если используете парсер, то делаете это на свой страх и риск %)
&НаСервере
Функция ВернутьСтрокуОбъекта(ПервыйСимвол,ПоследнийСимвол,СтрокаРеквизита)
КоличествоВложений=1;
СтрокаНабора="";
Для к=2 По СтрДлина(СтрокаРеквизита) Цикл
Символ=Сред(СтрокаРеквизита,к,1);
Если Символ=ПервыйСимвол ТОгда
КоличествоВложений=КоличествоВложений+1;
ИначеЕсли ПоследнийСимвол=Символ Тогда
КоличествоВложений=КоличествоВложений-1;
Конецесли;
Если КоличествоВложений=0 Тогда
Возврат СтрокаНабора;
КонецЕсли;
СтрокаНабора=СтрокаНабора+Символ;
КонецЦикла;
КонецФункции
&НаСервере
Процедура ПолучитьСтруктуруСтроки(ТаблицаОбъектов=Неопределено,СтрокаРеквизита,Родитель="",ТипРодителя=2,Позиция=1);
Если ТаблицаОбъектов=Неопределено Тогда
ТаблицаОБъектов=Новый ТаблицаЗначений;
ТаблицаОбъектов.Колонки.Добавить("Имя",Новый ОписаниеТипов("Строка"));
ТаблицаОбъектов.Колонки.Добавить("ТипОбъекта",Новый ОписаниеТипов("Число"));//0-объект,1-массив,2-прочий;
ТаблицаОбъектов.Колонки.Добавить("ПозицияВСтроке",Новый ОписаниеТипов("Число")); //позиция в строкеJSON
ТаблицаОбъектов.Колонки.Добавить("Вес",Новый ОписаниеТипов("Число")); //длина объекта
ТаблицаОбъектов.Колонки.Добавить("Родитель",Новый ОписаниеТипов("Строка"));//имя родителя
ТаблицаОбъектов.Колонки.Добавить("Состав",Новый ОписаниеТипов("Строка"));//текстовое содержание объекта
КонецЕсли;
ОбъектНайден=0;
ЭтоИмя=Ложь;
СтрокаОбъекта=Неопределено;
СчитаемВеса=Ложь;
ИмяРеквизита="";
Вес=0;
Для к=1 По СтрДлина(СтрокаРеквизита) Цикл
Символ=Сред(СтрокаРеквизита,к,1);
ВторойСимвол=Сред(СтрокаРеквизита,к+1,1);
Если Символ="\" Тогда //для спецсимволов (их пропускаем, нормализовать текст можно потом)
к=к+1;
Если СчитаемВеса ТОгда
Вес=Вес+2;
КонецЕсли;
Продолжить;
Конецесли;
Если СчитаемВеса ТОгда
Если Найти(""",]}",Символ)=0 Тогда
Вес=Вес+1;
Конецесли;
КонецЕсли;
Если Найти(",]}",Символ)>0 Или к=СтрДлина(СтрокаРеквизита) Тогда
Если СтрокаОбъекта<>Неопределено Тогда
СтрокаОбъекта.Вес=Вес;
СтрокаОбъекта.Состав=Сред(СтрокаРеквизита,СтрокаОбъекта.ПозицияВСтроке-Позиция+1,Вес); //для наглядности
КонецЕсли;
ЭтоИмя=Ложь;
СчитаемВеса=Ложь;
Вес=0;
СтрокаОбъекта=Неопределено;
ИмяРеквизита="";
Продолжить;
КонецЕсли;
Если Символ="""" и Не СчитаемВеса И ТипРодителя<>1 Тогда
ЭтоИмя=Не ЭтоИмя;
КонецеСли;
Если Не ЭтоИмя И Не СчитаемВеса И СтрокаОбъекта=Неопределено Тогда //Имя реквизита нашли, инвертировали признак имени, создаем реквизит
Вес=0;
СтрокаОбъекта=ТаблицаОбъектов.Добавить();
Если ИмяРеквизита="" Тогда
ИмяРеквизита=Строка(Новый УникальныйИдентификатор);
Конецесли;
СтрокаОбъекта.Имя=ИмяРеквизита;
СтрокаОбъекта.Родитель=Родитель;
СтрокаОбъекта.ТипОбъекта=2;
ИмяРеквизита="";
ИначеЕсли ЭтоИмя и Не СчитаемВеса Тогда
Если Символ<>"""" Тогда
ИмяРеквизита=ИмяРеквизита+Символ;
Конецесли;
КонецЕсли;
Если Символ=":" Или (ТипРодителя=1 и Символ="""") Тогда
СчитаемВеса=Истина;
Если СтрокаОбъекта<>Неопределено Тогда
Если ВторойСимвол="""" Тогда
СтрокаОбъекта.ПозицияВстроке=Позиция+к+1;
Иначе
СтрокаОбъекта.ПозицияВстроке=Позиция+к;
Конецесли;
КонецЕсли;
КонецЕсли;
Если Символ="{" Тогда //обрабатываем вложенные объекты
ВложеннаяСтрока=ВернутьСтрокуОбъекта("{","}",Прав(СтрокаРеквизита,СтрДлина(СтрокаРеквизита)-к+1));
Если СтрокаОбъекта<>Неопределено Тогда
СтрокаОбъекта.ПозицияВстроке=Позиция+к;
СтрокаОбъекта.Состав=ВложеннаяСтрока;
СтрокаОбъекта.ТипОбъекта=0;
СтрокаОбъекта.Вес=СтрДлина(ВложеннаяСтрока);
ПолучитьСтруктуруСтроки(ТаблицаОбъектов,ВложеннаяСтрока,СтрокаОбъекта.Имя,0,СтрокаОбъекта.ПозицияВстроке);
СчитаемВеса=Ложь;
СтрокаОбъекта=Неопределено;
Вес=0;
Иначе
ПолучитьСтруктуруСтроки(ТаблицаОбъектов,ВложеннаяСтрока,,Позиция+к);
КонецЕсли;
к=к+СтрДлина(ВложеннаяСтрока)+1;
КонецЕсли;
Если Символ="[" Тогда //обрабатываем вложенные массивы
ВложеннаяСтрока=ВернутьСтрокуОбъекта("[","]",Прав(СтрокаРеквизита,СтрДлина(СтрокаРеквизита)-к+1));
Если СтрокаОбъекта<>Неопределено Тогда
СтрокаОбъекта.ПозицияВстроке=Позиция+к;
СтрокаОбъекта.Состав=ВложеннаяСтрока;
СтрокаОбъекта.ТипОбъекта=1;
СтрокаОбъекта.Вес=СтрДлина(ВложеннаяСтрока);
ПолучитьСтруктуруСтроки(ТаблицаОбъектов,ВложеннаяСтрока,СтрокаОбъекта.Имя,1,СтрокаОбъекта.ПозицияВстроке);
СчитаемВеса=Ложь;
СтрокаОбъекта=Неопределено;
Вес=0;
Иначе
ПолучитьСтруктуруСтроки(ТаблицаОбъектов,ВложеннаяСтрока,,Позиция+к);
КонецЕсли;
к=к+СтрДлина(ВложеннаяСтрока)+1;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Использование: Вызываем процедуру
ПолучитьСтруктуруСтроки(ТаблицаОбъектов,СтрокаJSON);
ТаблицаОбъектов- пустая таблица значений в которую выгружаются объекты парсинга.
СтрокаJSON - строка, которую парсим.
После отработки процедуры таблица будет заполнена объектами строки json.
По значениям колонок "ПозицияВстроке" и "Вес" можно получить значение объекта из строки JSON
сред(СтрокаJSON,СтрокаТаблицы.ПозицияВстроке,СтрокаТаблицы.Вес)
или взять его же из колонки "Состав". Для объектов и массивов в "Состав" записывается строковое значение лежащее между скобками {} для объекта или [] для массива, со всеми внутренними вложениями.