Как удалить повторяющиеся символы и пробелы из строки в 1С

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

В процессе разработки часто возникает задача очистки данных, полученных от пользователя или из внешних систем. Одной из классических задач является удаление лишних пробелов и повторяющихся символов. Например, если на входе мы имеем строку "abc cde def", результатом обработки должна стать строка "abcdef". Разберем несколько способов решения этой задачи в среде 1С:Предприятие, проанализируем их эффективность и выберем оптимальный вариант для разных ситуаций.

Способ 1. Использование объекта «Соответствие» (наиболее производительный)

Проанализируем самый быстрый способ обработки длинных строк. Объект Соответствие (Match) идеально подходит для поиска уникальных элементов, так как поиск по ключу в нем реализован крайне эффективно. Основная идея заключается в том, чтобы обходить исходную строку посимвольно и добавлять каждый новый символ в Соответствие. Если символ уже встречался, мы его просто игнорируем.

Рассмотрим по шагам реализацию этого метода:

  1. Удалим все пробелы из исходной строки с помощью функции СтрЗаменить.
  2. Создадим объект Соответствие для хранения уникальных символов.
  3. Создадим Массив, в который будем складывать символы в порядке их появления (так как Соответствие не гарантирует сохранение порядка).
  4. В цикле проверим каждый символ: если его нет в ключах соответствия, добавим его туда и в массив.
  5. Соберем итоговую строку из массива.

// Входная строка
ИсходнаяСтрока = "abc cde def";

// Шаг 1: Убираем пробелы сразу
ЧистаяСтрока = СтрЗаменить(ИсходнаяСтрока, " ", "");

УникальныеСимволы = Новый Соответствие;
РезультатМассив = Новый Массив;

// Шаг 2-4: Обход строки
Для Сч = 1 По СтрДлина(ЧистаяСтрока) Цикл
    ТекущийСимвол = Сред(ЧистаяСтрока, Сч, 1);
    
    // Проверяем, встречался ли символ ранее
    Если УникальныеСимволы[ТекущийСимвол] = Неопределено Тогда
        УникальныеСимволы.Вставить(ТекущийСимвол, Истина);
        РезультатМассив.Добавить(ТекущийСимвол);
    КонецЕсли;
КонецЦикла;

// Шаг 5: Сборка результата
Результат = СтрСоединить(РезультатМассив, "");
// Результат будет "abcdef"

Важное замечание: В отличие от объекта Структура, объект Соответствие позволяет использовать в качестве ключа любые значения, включая цифры и спецсимволы, что критически важно при работе с произвольным текстом.

Способ 2. Простой перебор с функцией «СтрНайти»

Если строка небольшая и производительность не является критическим фактором, можно использовать более простой и читаемый код. Мы будем формировать результирующую строку, проверяя наличие текущего символа в уже собранном результате.

Рассмотрим пример реализации:


ИсходнаяСтрока = "abc cde def";
Результат = "";

Для А = 1 По СтрДлина(ИсходнаяСтрока) Цикл
    Симв = Сред(ИсходнаяСтрока, А, 1);
    
    // Проверяем: если это не пробел и символа еще нет в результате
    Если Симв <> " " И СтрНайти(Результат, Симв) = 0 Тогда
        Результат = Результат + Симв;
    КонецЕсли;
КонецЦикла;

Выясним причину, по которой этот метод может работать медленнее на больших объемах данных. При каждой операции Результат = Результат + Симв система 1С создает в памяти новую строку, копируя в нее содержимое старой. На строках в десятки тысяч символов это может вызвать заметные задержки.

Способ 3. Метод последовательного исключения (СтрЗаменить)

Существует еще один интересный алгоритм, который «вырезает» найденный символ из всей оставшейся части строки. Это позволяет сократить количество итераций цикла в некоторых случаях.


ВходящаяСтрока = "abc cde def";
// Предварительно удаляем пробелы
ВходящаяСтрока = СтрЗаменить(ВходящаяСтрока, " ", "");
Результат = "";

Пока СтрДлина(ВходящаяСтрока) > 0 Цикл
    // Берем самый первый символ
    ТекущийСимвол = Лев(ВходящаяСтрока, 1);
    Результат = Результат + ТекущийСимвол;
    
    // Удаляем ВСЕ вхождения этого символа из оставшейся строки
    ВходящаяСтрока = СтрЗаменить(ВходящаяСтрока, ТекущийСимвол, "");
КонецЦикла;

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

Способ 4. Использование «Таблицы Значений» (Универсальный подход)

Иногда программисты предпочитают использовать встроенные механизмы агрегации 1С, такие как метод Свернуть() у объекта ТаблицаЗначений. Несмотря на то, что этот метод требует вызова сервера (так как таблицы значений недоступны на тонком клиенте без контекста), он может быть удобен, если данные в дальнейшем нужно сортировать или обрабатывать как коллекцию.

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

  1. Разложим строку в таблицу, где каждая строка таблицы — один символ.
  2. Применим метод Свернуть по колонке с символом.
  3. Соберем данные обратно в строку.

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Символ");

Для Сч = 1 По СтрДлина(Строка) Цикл
    ТекСимвол = Сред(Строка, Сч, 1);
    Если ТекСимвол <> " " Тогда
        ТЗ.Добавить().Символ = ТекСимвол;
    КонецЕсли;
КонецЦикла;

// Магия 1С: удаляем дубли одной командой
ТЗ.Свернуть("Символ");

Результат = "";
Для Каждого Стр Из ТЗ Цикл
    Результат = Результат + Стр.Символ;
КонецЦикла;

Нюансы, которые важно учитывать

Проанализируем технические тонкости, которые могут повлиять на результат работы ваших алгоритмов:

Подводя итог, можно сказать, что для большинства повседневных задач оптимальным является Способ 1 (Соответствие + Массив), так как он обеспечивает стабильную скорость и корректно обрабатывает любые символы в строке.

← На главную