Как декодировать JSON-строку с Unicode-символами вида \uXXXX в нормальный текст в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними системами (через Web-API, HTTP-сервисы или при чтении текстовых файлов) разработчики часто сталкиваются со строками, в которых кириллические символы заменены на escape-последовательности Unicode. Например, вместо понятного текста «а-2 б-2 в-4» в переменной содержится строка вида \u0430-2 \u0431-2 \u0432-4.

В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем решения, предложенные участниками форума, а также рассмотрим более производительные и современные способы декодирования таких строк в платформе 1С:Предприятие 8.3.

Способ 1. Искусственное оборачивание в JSON-структуру (Решение с форума)

Участники обсуждения на форуме обратили внимание, что прямая запись закодированной строки через объект ЗаписьJSON приводит к повторному экранированию символов (обратный слэш удваивается, превращаясь в \\uXXXX). В результате на выходе получается та же самая недекодированная строка.

Чтобы заставить платформу корректно проанализировать и декодировать спецсимволы, было предложено «обмануть» парсер: искусственно преобразовать исходную плоскую строку в полноценный JSON-объект (структуру с ключом и значением) с помощью строковой конкатенации, а затем прочитать этот объект штатными средствами 1С.

Проанализируем алгоритм этого решения по шагам:

  1. Берем исходную закодированную строку.
  2. Добавляем к ней фигурные скобки и имя свойства, чтобы получился валидный JSON-объект: {"Строка": "значение"}.
  3. Создаем объект ЧтениеJSON и передаем ему полученную строку.
  4. Вызываем метод ПрочитатьJSON, который автоматически преобразует escape-последовательности Юникода в нормальные символы кириллицы.

Посмотрим на пример реализации данного подхода:


ИсходнаяСтрока = "\u0430-2 \u0431-2 \u0432-4";

// Искусственно формируем структуру JSON-объекта
СтрокаJSON = "{""Строка"":""" + ИсходнаяСтрока + """}";

Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);

// Получаем объект Соответствие или Структуру с декодированным значением
РезультатОбъект = ПрочитатьJSON(Чтение);
Чтение.Закрыть();

// Извлекаем наше значение
ДекодированнаяСтрока = РезультатОбъект["Строка"];
Сообщить(ДекодированнаяСтрока); // В окне сообщений выведется: а-2 б-2 в-4

Этот метод полностью рабочий, однако он имеет недостаток: избыточность. Для декодирования одной текстовой переменной нам приходится инициализировать в оперативной памяти объект типа Структура или Соответствие, что снижает общую производительность кода.

Способ 2. Декодирование через JSON-примитив (Оптимальный вариант)

Разберем распространенное заблуждение, прозвучавшее на форуме: утверждение о том, что «1С ничего не знает про таблицу символов Юникод». Начиная с версии 8.3.6, платформа нативно поддерживает стандарт RFC 4627 и великолепно декодирует любые последовательности вида \uXXXX.

Согласно спецификации формата JSON, валидным документом может выступать не только объект (в фигурных скобках) или массив (в квадратных скобках), но и обычный JSON-примитив. В частности — простая строка, заключенная в двойные кавычки.

Это означает, что нам не нужно создавать сложные структуры. Достаточно просто добавить к нашей закодированной строке двойные кавычки по бокам и прочитать её напрямую через ПрочитатьJSON. Выясним, насколько лаконичнее становится наш код:


ИсходнаяСтрока = "\u0430-2 \u0431-2 \u0432-4";

// Оборачиваем строку в двойные кавычки, чтобы превратить её в валидный примитив JSON
СтрокаJSON = """" + ИсходнаяСтрока + """";

Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);

// Читаем напрямую в строковую переменную
Результат = ПрочитатьJSON(Чтение);
Чтение.Закрыть();

Сообщить(Результат); // Результат: а-2 б-2 в-4

Преимущества этого подхода:

Способ 3. Использование готового функционала БСП

Если вы пишете код в любой современной типовой конфигурации 1С (ERP, Управление торговлей, Бухгалтерия предприятия, ЗУП и др.), то в вашем распоряжении имеется Библиотека Стандартных Подсистем (БСП). В БСП уже встроены готовые функции-обертки, которые позволяют избавиться от ручного создания объектов ЧтениеJSON.

В зависимости от версии БСП в вашей системе, вы можете использовать готовые служебные методы общего назначения. Например:

Под капотом эти функции используют те же механизмы чтения JSON-структур, но избавляют вас от написания шаблонного кода.

Способ 4. Решения для устаревших платформ (ниже версии 8.3.6)

Рассмотрим ситуации, когда разработка ведется на старых версиях платформы (например, 1С 8.2 или ранних релизах 8.3), где встроенный объект ЧтениеJSON отсутствует. В этом случае мы можем применить два альтернативных метода декодирования.

Вариант А. Программный парсинг Hex-кодов

Напишем собственную функцию разбора строки. Суть алгоритма: находим в строке вхождения спецсимвола \u, извлекаем идущие следом 4 шестнадцатеричных символа (Hex-код), переводим их в десятичную систему счисления (Dec) и восстанавливаем символ встроенной функцией Символ().

Посмотрим на программную реализацию:


Функция ДекодироватьЮникод(Знач ВходнаяСтрока) Экспорт
    Результат = "";
    Поз = Найти(ВходнаяСтрока, "\u");
    
    Пока Поз > 0 Цикл
        // Добавляем текст, который шел до спецсимвола
        Результат = Результат + Лев(ВходнаяСтрока, Поз - 1);
        
        // Извлекаем 4 символа шестнадцатеричного кода
        КодHex = Сред(ВходнаяСтрока, Поз + 2, 4);
        
        // Переводим Hex в десятичное число
        КодDec = HexToDec(КодHex);
        
        // Преобразуем число в символ и добавляем в результат
        Результат = Результат + Символ(КодDec);
        
        // Отрезаем обработанную часть строки
        ВходнаяСтрока = Сред(ВходнаяСтрока, Поз + 6);
        Поз = Найти(ВходнаяСтрока, "\u");
    КонецЦикла;
    
    Результат = Результат + ВходнаяСтрока;
    Возврат Результат;
КонецФункции

Функция HexToDec(Знач ЗначениеHex)
    СимволыHex = "0123456789ABCDEF";
    ЗначениеHex = ВРег(ЗначениеHex);
    Результат = 0;
    
    Для Индекс = 1 По СтрДлина(ЗначениеHex) Цикл
        СимволHex = Сред(ЗначениеHex, Индекс, 1);
        Поз = Найти(СимволыHex, СимволHex) - 1;
        Результат = Результат * 16 + Поз;
    КонецЦикла;
    
    Возврат Результат;
КонецФункции

Данный вариант полностью универсален, работает на любой версии платформы (включая 1С 7.7) и не зависит от операционной системы.

Вариант Б. Использование MSScriptControl (только под ОС Windows)

Если код выполняется в среде операционной системы Windows, можно задействовать COM-объект MSScriptControl.ScriptControl с языком JavaScript, который нативно умеет обрабатывать кодировку Unicode.

Разберем этот простой пример:


// Инициализируем COM-объект
JS = Новый COMОбъект("MSScriptControl.ScriptControl");
JS.Language = "JScript";

ИсходнаяСтрока = "\u0430-2 \u0431-2 \u0432-4";

// Передаем строку в JS движок для мгновенного декодирования
ДекодированнаяСтрока = JS.Eval("'" + ИсходнаяСтрока + "'");

Сообщить(ДекодированнаяСтрока); // Результат: а-2 б-2 в-4

Важное ограничение: этот способ привязан к операционной системе Windows и не будет работать на серверах под управлением Linux. Также могут возникнуть проблемы совместимости при работе в 64-битных рабочих процессах сервера 1С.

Резюме

Мы проанализировали несколько подходов к решению проблемы декодирования Unicode-символов. Для современных конфигураций 1С самым быстрым, лаконичным и надежным является Способ 2 (Декодирование через примитив JSON), так как он использует эффективный встроенный парсер платформы и не требует создания лишних объектов в памяти.

← На главную