В процессе разработки отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда текстовые данные (например, история чата, комментарии или описания товаров) хранятся в базе в формате HTML. При выводе таких данных в отчет пользователь видит нагромождение тегов типа <div>, <p> или <br>, что делает информацию нечитаемой.
В этой статье мы подробно разберем несколько проверенных способов очистки строки от HTML-разметки, проанализируем их плюсы и минусы, а также выясним, как обойти ограничения безопасного режима.
Если ваша конфигурация разработана на базе Библиотеки стандартных подсистем (БСП), это самый быстрый и надежный метод. В составе БСП есть готовый общий модуль СтроковыеФункцииКлиентСервер, который содержит необходимый функционал.
Рассмотрим, как применить это в СКД:
ТекстБезHTML).
СтроковыеФункцииКлиентСервер.ИзвлечьТекстИзHTML(ИмяВашегоПоляСHTML)
Преимущества: метод корректно обрабатывает не только теги, но и спецсимволы (например, заменяет на обычные пробелы).
Регулярные выражения позволяют эффективно удалять любые конструкции, заключенные в угловые скобки. Однако здесь есть важный нюанс: использование VBScript.RegExp через COM-объект часто блокируется платформой, если установлен безопасный режим.
Разберем создание функции в общем модуле. Создадим модуль, например, РаботаСТекстомСервер, установим флаги Сервер и Вызов сервера.
Функция ОчиститьHTML(ТекстHTML) Экспорт
Если ПустаяСтрока(ТекстHTML) Тогда
Возврат "";
КонецЕсли;
// Для платформы 8.3.24+ используем нативный объект
// Если версия ниже, используем COMОбъект "VBScript.RegExp"
Попытка
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.MultiLine = Истина;
RegExp.Pattern = "<[^>]*>"; // Шаблон для поиска любых тегов
Возврат RegExp.Replace(ТекстHTML, "");
Исключение
// Если COM не доступен (Linux или безопасный режим),
// используем запасной вариант со строковыми функциями
Возврат ОчиститьСтроковымиФункциями(ТекстHTML);
КонецПопытки;
КонецФункции
После этого в вычисляемом поле СКД достаточно написать: РаботаСТекстомСервер.ОчиститьHTML(ТекстЧат).
Проанализируем более профессиональный подход, который не зависит от операционной системы и работает быстрее COM-объектов. Мы воспользуемся объектами ЧтениеHTML и ПостроительDOM.
Этот метод позволяет платформе 1С самостоятельно разобрать структуру документа и извлечь из него только текстовое содержимое. Разберем реализацию функции:
Функция ИзвлечьТекстDOM(Знач ИсходныйHTML) Экспорт
Чтение = Новый ЧтениеHTML;
// Метод УстановитьСтроку позволяет не использовать временные файлы
Чтение.УстановитьСтроку(ИсходныйHTML);
Построитель = Новый ПостроительDOM;
ДокументDOM = Построитель.Прочитать(Чтение);
// Свойство ТекстовоеСодержимое возвращает чистый текст без тегов
Результат = ДокументDOM.Тело.ТекстовоеСодержимое;
Чтение.Закрыть();
Возврат Результат;
КонецФункции
Важный момент: этот способ является наиболее предпочтительным, так как он корректно обрабатывает вложенные структуры и не требует регистрации дополнительных библиотек в системе.
Иногда у программиста нет возможности менять конфигурацию (добавлять общие модули), а отчет нужно выпустить здесь и сейчас. В таком случае можно попытаться очистить текст прямо в выражении СКД, используя функции СтрНайти, Сред и СтрЗаменить.
Рассмотрим пример для удаления конкретных тегов, если структура HTML всегда одинакова:
СтрЗаменить(СтрЗаменить(Сред(ПолеHTML, СтрНайти(ПолеHTML, ">") + 1), "</div>", ""), "<br>", "")
Проанализируем этот подход: он крайне нестабилен. Если в HTML добавится лишний пробел или атрибут (например, <div style="...">), формула перестанет работать. Используйте этот метод только в самых крайних случаях для простых строк.
Если данных в отчете очень много, вызов функции для каждой строки может замедлить формирование. В этом случае мы можем перехватить процесс формирования отчета в модуле объекта отчета.
Выясним алгоритм действий:
ПриКомпоновкеРезультата.
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Настройки и компоновка
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
// Выгружаем в таблицу
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ТаблицаРезультат = Новый ТаблицаЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Массовая обработка данных
Для Каждого Строка Из ТаблицаРезультат Цикл
Строка.ТекстСообщения = РаботаСТекстомСервер.ИзвлечьТекстDOM(Строка.ТекстСообщения);
КонецЦикла;
// Вывод обработанной таблицы в документ
// (Дальнейший код вывода в табличный документ)
КонецПроцедуры
Проанализировав все ситуации, подведем итог:
СтроковыеФункцииКлиентСервер.ИзвлечьТекстИзHTML.ПостроительDOM.RegExp через COM и используйте нативные функции платформы (DOM или ФорматированныйДокумент).Помните, что простая замена скобок через СтрЗаменить не удаляет невидимые символы и сущности типа ", поэтому всегда лучше отдавать предпочтение штатным парсерам платформы 1С.