В практике разработчика 1С часто встречается задача разбора текстовых данных, представленных во внутреннем формате платформы (так называемый «скобкофайл» или V8 File Format). Это могут быть файлы конфигурации, выгрузки настроек, логи замера производительности или просто текстовые строки вида "{0,{1,2}}". Наша цель — превратить такую строку в полноценный объект Массив, где каждый вложенный блок скобок станет вложенным массивом.
В этой статье мы подробно разберем несколько подходов: от быстрого «хака» через JSON до профессионального потокового парсинга больших файлов. Мы проанализируем преимущества каждого метода и выясним, какие подводные камни могут встретиться на пути.
Если ваша строка имеет простую структуру, где данные разделены запятыми, а уровни вложенности обозначены фигурными скобками, мы можем воспользоваться тем, что синтаксис массивов в JSON практически идентичен формату 1С, за исключением самих символов скобок. В JSON используются квадратные скобки [], а в 1С — фигурные {}.
Рассмотрим по шагам процесс преобразования:
ЧтениеJSON для десериализации строки.Посмотрим на пример программного кода, который реализует этот алгоритм:
&НаКлиенте
Процедура ПреобразоватьСтрокуВМассив(ИсходныйТекст)
// Шаг 1: Подготовка строки
ТекстJSON = СтрЗаменить(ИсходныйТекст, "{", "[");
ТекстJSON = СтрЗаменить(ТекстJSON, "}", "]");
// Шаг 2: Чтение данных
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстJSON);
Попытка
Результат = ПрочитатьJSON(Чтение);
// Теперь переменная 'Результат' содержит вложенные массивы
СообщитьРек(Результат);
Исключение
Сообщить("Ошибка парсинга: возможно, в тексте есть некорректные символы или кавычки.");
КонецПопытки;
КонецПроцедуры
Процедура СообщитьРек(М, Уровень = 0)
Отступ = "";
Для Сч = 1 По Уровень Цикл
Отступ = Отступ + " ";
КонецЦикла;
Для Каждого Элемент ИЗ М Цикл
Если ТипЗнч(Элемент) = Тип("Массив") Тогда
Сообщить(Отступ + "Вложенный массив:");
СообщитьРек(Элемент, Уровень + 1);
Иначе
Сообщить(Отступ + Элемент);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Важное ограничение: Этот метод отлично работает с числами и простыми строками. Однако, если внутри фигурных скобок находятся строковые данные, содержащие запятые или кавычки, обычная функция СтрЗаменить может нарушить структуру данных. Также помните, что в JSON строковые значения обязательно должны быть заключены в двойные кавычки. Если в вашем «скобкофайле» строки идут без кавычек, ПрочитатьJSON выдаст ошибку.
Если исходная строка является результатом работы стандартных механизмов 1С (например, ЗначениеВСтрокуВнутр), то правильнее всего использовать обратную функцию. Внутренний формат 1С для массива всегда начинается со специфического идентификатора типа.
Проанализируем ситуацию: если ваша строка — это просто "{0,{1,2}}", она не является валидной для ЗначениеИзСтрокиВнутр. Чтобы она заработала, ее нужно обернуть в заголовок массива. Структура массива во внутреннем формате выглядит примерно так: {"#",51e7a0d2-530b-11d4-b98a-008048da30aa,{...}}, где GUID — это уникальный идентификатор типа Массив.
Этот метод считается наиболее надежным для восстановления сложных типов данных (дат, ссылок, уникальных идентификаторов), так как платформа сама управляет типизацией.
Выясним причину, по которой первые два метода могут не подойти. Если ваш текст занимает десятки или сотни мегабайт, попытка загрузить его целиком в память и выполнить СтрЗаменить может привести к аварийному завершению сеанса из-за нехватки ресурсов. В таких случаях мы рекомендуем использовать посимвольное чтение.
Разберем логику алгоритма на базе стека:
ЧтениеТекста.{: создаем новый массив, добавляем его в «ТекущийМассив», сохраняем «ТекущийМассив» в стек и делаем новый массив текущим.,: если мы не внутри кавычек, значит, текущее накопленное значение (между скобкой или запятой) нужно добавить в массив.}: завершаем наполнение текущего массива и извлекаем из стека родительский массив, делая его текущим.Такой подход позволяет обрабатывать файлы любого размера, так как в памяти одновременно находится только дерево массивов, а не весь исходный текст целиком.
Существует еще один «хакерский» метод. Мы можем преобразовать строку "{0,{1,2}}" в исполняемый код 1С, заменив фигурные скобки на вызовы конструктора массива. Итоговая строка должна выглядеть так: "Новый Массив(0, Новый Массив(1, 2))" (в упрощенном виде, на самом деле конструктор массива в 1С не принимает список элементов напрямую, поэтому потребуется вспомогательная функция).
Внимание: Мы крайне не рекомендуем использовать функцию Вычислить() для данных, полученных извне. Это создает критическую уязвимость в безопасности: если злоумышленник подставит в текстовый файл команду удаления файлов или выполнения вредоносного кода, платформа исполнит ее с правами текущего пользователя.
При реализации любого из методов нужно учитывать нюансы экранирования:
"" превращаются в одну при чтении.YYYYMMDDHHMMSS.Если вам требуется профессиональный разбор сложных конфигурационных файлов, рекомендуем обратить внимание на наработки сообщества (например, парсеры от ZhokhovM или инструменты анализа замеров производительности от tormozit), которые реализуют полноценные конечные автоматы для разбора этого формата.
Подводя итог, для большинства повседневных задач метод с ЧтениеJSON является оптимальным по соотношению сложности и скорости разработки. Рассмотрим еще раз финальную структуру решения задачи:
// Пример функции для очистки и подготовки простых данных
Функция ПреобразоватьПростуюСтроку(Знач Стр)
Стр = СтрЗаменить(Стр, "{", "[");
Стр = СтрЗаменить(Стр, "}", "]");
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Стр);
Возврат ПрочитатьJSON(Чтение);
КонецФункции
Используйте этот код как основу, дополняя его проверками на корректность входных данных и обработкой исключений. Совместное использование стандартных функций платформы и понимание структуры данных позволит вам эффективно решать задачи интеграции и обработки внутренних форматов 1С.