В процессе разработки на платформе 1С:Предприятие 8 часто возникает задача разделения одной длинной строки на части по определенному разделителю (например, точка с запятой, запятая или перенос строки). Те, кто пришел из версии 7.7, помнят удобный метод ИзСтрокиСРазделителями(). В восьмой версии платформы подходы изменились, стали более гибкими, но и требуют понимания контекста использования.
Рассмотрим подробно все существующие способы: от простых встроенных функций до сложных алгоритмов разбора CSV-формата.
Начиная с версии 8.3.6, разработчики получили долгожданный нативный инструмент, который работает максимально быстро, так как реализован на уровне ядра платформы. Проанализируем синтаксис этой функции:
СтрРазделить(Строка, Разделитель, ВключатьПустые)
Разберем параметры подробнее:
Истина, то при наличии двух разделителей подряд в массив будет добавлен пустой элемент. Это критично для сохранения структуры колонок при импорте данных.Рассмотрим практический пример использования:
// Исходная строка с данными
ТекСтр = "А;В;;С";
// Разделяем строку, игнорируя пустые значения
МассивБезПустых = СтрРазделить(ТекСтр, ";", Ложь);
// Результат: ["А", "В", "С"]
// Разделяем строку, сохраняя пустые значения
МассивСПустыми = СтрРазделить(ТекСтр, ";", Истина);
// Результат: ["А", "В", "", "С"]
Этот метод является приоритетным для использования во всех современных конфигурациях.
Если вы работаете в типовой конфигурации (например, Бухгалтерия предприятия 3.0 или Управление торговлей 11), в вашем распоряжении есть готовые функции общего назначения. Проанализируем возможности модуля СтроковыеФункцииКлиентСервер.
Наиболее популярная функция — РазложитьСтрокуВМассивПодстрок. Она удобна тем, что корректно обрабатывает параметры и часто уже «прописана» в логике конфигурации.
// Пример использования БСП
Разделитель = ";";
ТекСтр = "Иванов;Петров;Сидоров";
МассивРезультат = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ТекСтр, Разделитель);
Также в БСП есть полезная функция РазложитьСтрокуВМассивСлов, которая разбивает текст, используя в качестве разделителей любые неалфавитные символы (пробелы, знаки препинания и т.д.).
До появления встроенной функции программисты часто использовали элегантный трюк с подменой разделителя на символ переноса строки. Это позволяет использовать встроенные функции работы с многострочным текстом. Рассмотрим этот алгоритм:
// Исходные данные
ТвояСтрока = "Яблоко;Груша;Слива";
Разделитель = ";";
// Шаг 1: Заменяем ваш разделитель на системный символ переноса строки
ТекстСПереносами = СтрЗаменить(ТвояСтрока, Разделитель, Символы.ПС);
// Шаг 2: Обходим строки в цикле
СписокПродуктов = Новый СписокЗначений;
Для НомерСтроки = 1 По СтрЧислоСтрок(ТекстСПереносами) Цикл
ТекущееЗначение = СтрПолучитьСтроку(ТекстСПереносами, НомерСтроки);
СписокПродуктов.Добавить(ТекущееЗначение);
КонецЦикла;
Важное примечание: данный метод работает быстро, но его стоит с осторожностью применять на очень больших объемах текста (десятки мегабайт), так как функция СтрПолучитьСтроку при каждом вызове заново пересчитывает символы с начала текста.
Выясним причину, по которой стандартные методы иногда пасуют. В форматах типа CSV (например, банковские выписки) разделитель может встречаться внутри текстового поля, заключенного в кавычки. Например: "Оплата по счету №123; за услуги"; 1500.00. Если просто разбить эту строку по ;, мы получим неверное количество колонок.
Для решения этой задачи разработаем алгоритм «ручного» разбора с флагом состояния кавычек. Посмотрим на пример функции:
Функция РазобратьСтрокуСКавычками(ИсходнаяСтрока, Разделитель = ";", СимволКавычки = """")
РезультатМассив = Новый Массив;
ВнутриКавычек = Ложь;
ТекущаяПодстрока = "";
Для Индекс = 1 По СтрДлина(ИсходнаяСтрока) Цикл
Символ = Сред(ИсходнаяСтрока, Индекс, 1);
Если Символ = СимволКавычки Тогда
// Меняем состояние (зашли в кавычки или вышли из них)
ВнутриКавычек = НЕ ВнутриКавычек;
ТекущаяПодстрока = ТекущаяПодстрока + Символ;
ИначеЕсли (Символ = Разделитель) И (НЕ ВнутриКавычек) Тогда
// Нашли разделитель вне кавычек - фиксируем подстроку
РезультатМассив.Добавить(ТекущаяПодстрока);
ТекущаяПодстрока = "";
Иначе
// Обычный символ или разделитель внутри кавычек
ТекущаяПодстрока = ТекущаяПодстрока + Символ;
КонецЕсли;
КонецЦикла;
// Добавляем последний фрагмент
РезультатМассив.Добавить(ТекущаяПодстрока);
Возврат РезультатМассив;
КонецФункции
Этот метод гарантирует, что ; внутри назначения платежа не приведет к разрыву строки там, где это не нужно. Проанализируем ситуацию: использование такого цикла — единственный надежный способ без использования внешних библиотек (типа RegExp) корректно прочитать «кривой» CSV-файл.
Часто после обработки массива данных его нужно собрать обратно в строку. В новых версиях платформы для этого существует функция СтрСоединить.
МассивИмен = Новый Массив;
МассивИмен.Добавить("Администратор");
МассивИмен.Добавить("Бухгалтер");
// Собираем в строку через запятую
ИтоговаяСтрока = СтрСоединить(МассивИмен, ", ");
// Результат: "Администратор, Бухгалтер"
Это гораздо эффективнее, чем конкатенация в цикле (Строка = Строка + Элемент + ";"), так как не создает лишних промежуточных объектов в памяти.
Для выбора оптимального метода придерживайтесь следующих правил:
СтрРазделить.ОбщегоНазначения или СтроковыеФункцииКлиентСервер, там могут быть расширенные версии методов.СтрСоединить.Правильный выбор метода обеспечит не только быстродействие вашей обработки, но и стабильность при работе с нестандартными данными.