Выделить значение до маркера и выбрать самый длинный совпадающий маркер

Учебные задачи

В строке KEY:Книга##TAIL маркеры # и ## совпадают в одном месте. Выбирается ##, а хвост читается отдельно.

Где и как запускать

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

  1. Используйте отдельную учебную базу. Фрагмент без директив вставьте в тело серверной процедуры ВыполнитьПример() Экспорт общего модуля УчебныеЗадачи.

  2. Все исходные байты создаются самим примером в памяти. Файлы, сеть, справочники и документы не нужны.

  3. Запускайте задачи отдельно. После закрытия ЧтениеДанных/ЗаписьДанных не используйте этот экземпляр повторно.

Данные = ПолучитьДвоичныеДанныеИзСтроки("KEY:Книга##TAIL", КодировкаТекста.UTF8, Ложь);
Чтение = Новый ЧтениеДанных(Данные, КодировкаТекста.UTF8);
Попытка
    Маркеры = Новый Массив;
    Маркеры.Добавить("#");
    Маркеры.Добавить("##");
    Значение = Чтение.ПрочитатьДо(Маркеры, КодировкаТекста.UTF8);
    Если Не Значение.МаркерНайден Тогда
        ВызватьИсключение "Не найден обязательный разделитель учебного сообщения";
    КонецЕсли;
    Сообщить(Значение.ИндексМаркера = 1);
    ТекстЗначения = ПолучитьСтрокуИзБуфераДвоичныхДанных(Значение.ПолучитьБуферДвоичныхДанных(), КодировкаТекста.UTF8);
    Сообщить(ТекстЗначения = "KEY:Книга");
    Остаток = Чтение.ПрочитатьДо("НЕСУЩЕСТВУЮЩИЙ", КодировкаТекста.UTF8);
    Сообщить(Не Остаток.МаркерНайден);
    Сообщить(ПолучитьСтрокуИзДвоичныхДанных(Остаток.ПолучитьДвоичныеДанные(), КодировкаТекста.UTF8) = "TAIL");
Исключение
    Чтение.Закрыть();
    ВызватьИсключение;
КонецПопытки;
Чтение.Закрыть();

Разбор по шагам

  1. Массив хранит два маркера с нулевыми индексами 0 и 1.

  2. ПрочитатьДо ищет ближайшую границу, а среди совпадений в этой позиции — маркер максимально возможной длины. Поэтому индекс 1 соответствует ##.

  3. Сначала проверяем МаркерНайден, затем используем ИндексМаркера. Не полагаемся на индекс при отсутствии маркера.

  4. Результат содержит данные перед границей, а не сам маркер. Следующее чтение начинается после ##.

  5. Если второго заданного маркера нет, результат всё равно содержит остаток TAIL, но МаркерНайден равно Ложь. Это нужно обработать как отдельную ситуацию.

Как проверить результат

  1. Первое значение KEY:Книга и индекс 1; второе значение TAIL без найденного маркера.

  2. Все четыре сравнения Истина; обязательная граница не теряется среди коротких совпадений.

Ожидаемый результат

Разобрано сообщение с конкурирующими границами и отсутствующим маркером.

На что обратить внимание

  1. Это учебный протокол, не готовый парсер HTTP multipart/CSV. Там есть дополнительные правила экранирования и границ.

  2. Не декодируйте произвольный двоичный payload как UTF-8: кодировка относится к текстовой части.

  3. ПолучитьБуферДвоичныхДанных загружает результат целиком в память; для больших частей используйте поток.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.