Разработка и Конфигурация · 9 мин
Как разделить строку на подстроки в 1С
Разбираем, как разделить строку на подстроки в 1С: функция СтрРазделить, работа с разделителями, обход массива, типичные ошибки и решения для старых версий платформы.
Задача разделить строку на подстроки возникает в 1С постоянно: при разборе ФИО на фамилию, имя и отчество, при обработке CSV-файлов, при парсинге артикулов, составленных из нескольких кодов, при чтении ответов веб-сервисов. Во встроенном языке для этого есть готовая функция СтрРазделить(), а для старых версий платформы — проверенные обходные приёмы.
Выбор способа зависит от версии платформы, характера разделителя (один символ или строка) и того, нужно ли сохранять пустые элементы. Ниже разобраны основные подходы с готовыми примерами кода, которые можно вставить в модуль и сразу проверить.
Функция СтрРазделить: синтаксис и базовый пример
Функция СтрРазделить() доступна в глобальном контексте начиная с платформы 8.3.6. Она принимает три параметра: исходную строку, разделитель и необязательный признак включения пустых строк. Результат — массив строк, который можно обойти в цикле или адресовать по индексу.
СтрокаКодов = "Молоко;Хлеб;Сахар";
МассивТоваров = СтрРазделить(СтрокаКодов, ";");
Для Каждого Элемент Из МассивТоваров Цикл
Сообщить(Элемент);
КонецЦикла;
Если разделитель не указан, по умолчанию используется запятая. Это удобно при разборе списков, представленных через запятую, но легко забыть и получить неожиданный результат, когда фактический разделитель другой. Всегда указывайте разделитель явно — это делает код самодокументируемым.
Обращение к элементам массива идёт по индексу с нуля: МассивТоваров[0] вернёт «Молоко». Перед обращением по индексу проверяйте размер массива через МассивТоваров.Количество(), иначе при неожиданно короткой строке получите ошибку обращения за границу массива.
Части = СтрРазделить("Иванов;Иван;Иванович", ";");
Фамилия = Части[0];
Имя = ?(Части.Количество() > 1, Части[1], "");Управление пустыми подстроками
Третий параметр функции определяет, попадут ли в результат пустые элементы, возникающие при двух разделителях подряд или при разделителе в начале либо конце строки. По умолчанию параметр равен Истина, то есть пустые строки включаются.
// Включая пустые: получим массив из 4 элементов, один из них пустой
Результат = СтрРазделить("А;;Б;В", ";", Истина);
// Без пустых: массив из 3 элементов
Результат = СтрРазделить("А;;Б;В", ";", Ложь);
Режим с включёнными пустыми строками критичен при разборе форматов с фиксированным числом полей, например строк CSV: пропущенное значение в середине строки должно сохранить свою позицию, иначе столбцы «съедут». Если же вы разбираете список, введённый пользователем вручную, пустые элементы обычно лучше отбросить, чтобы не обрабатывать лишние итерации.
Разделитель из нескольких символов и перенос строки
В отличие от некоторых языков, в 1С разделитель в СтрРазделить() — это строка, а не набор символов. Если передать «;», строка будет резаться именно по последовательности этих символов целиком, а не по каждому из них. Это частая причина ошибок у разработчиков, привыкших к другим языкам.
Для разбиения многострочного текста на строки разделителем служит символ переноса: Символы.ПС или комбинация Символы.ВК + Символы.ПС для текста, пришедшего из Windows-файлов. Надёжнее сначала нормализовать переносы через СтрЗаменить(), а потом делить по Символы.ПС.
Текст = СтрЗаменить(Текст, Символы.ВК + Символы.ПС, Символы.ПС);
Строки = СтрРазделить(Текст, Символы.ПС);
Разбиение строки на старых версиях платформы
На платформах ниже 8.3.6 функции СтрРазделить() нет, и приходится использовать один из двух классических приёмов. Первый — замена разделителя на символ переноса строки и чтение подстрок через СтрПолучитьСтроку(). Способ простой, но требует, чтобы разделитель был одним символом и чтобы сама строка не содержала переносов.
Функция РазделитьСтроку(Знач Строка, Разделитель)
Строка = СтрЗаменить(Строка, Разделитель, Символы.ПС);
Результат = Новый Массив;
Для Н = 1 По СтрЧислоСтрок(Строка) Цикл
Результат.Добавить(СтрПолучитьСтроку(Строка, Н));
КонецЦикла;
Возврат Результат;
КонецФункции
Второй приём — цикл с поиском позиции разделителя через Найти() и отсечением обработанной части через Сред(). Он универсальнее: работает с многосимвольными разделителями и не боится переносов строк внутри данных. На очень длинных строках он медленнее из-за многократного копирования строки, поэтому для больших объёмов предпочтителен вариант с СтрЗаменить().
Позиция = Найти(Строка, Разделитель);
Пока Позиция > 0 Цикл
Результат.Добавить(Лев(Строка, Позиция - 1));
Строка = Сред(Строка, Позиция + СтрДлина(Разделитель));
Позиция = Найти(Строка, Разделитель);
КонецЦикла;
Результат.Добавить(Строка); // последний фрагмент
Сравнение вариантов
Штатный и самый быстрый способ; ограничение — недоступен на старых релизах платформы.
Подходит для старых версий и односимвольного разделителя; ломается, если в данных есть переносы строк.
Универсален, работает с многосимвольными разделителями; медленнее на длинных строках.
Обратная операция и смежные задачи
Для сборки строки из массива используется функция СтрСоединить() — она принимает массив строк и разделитель. Пара «СтрРазделить / СтрСоединить» удобна, когда нужно удалить или заменить один элемент списка: разбиваете строку, меняете массив, собираете обратно.
Массив = СтрРазделить("А;Б;В", ";");
Массив.Удалить(1);
НоваяСтрока = СтрСоединить(Массив, ";"); // "А;В"
Если нужно разделить строку на части фиксированной длины (например, разбить длинный код на группы по 4 символа), СтрРазделить() не поможет — используйте цикл по Сред(Строка, Н, 4) с шагом 4. А для разбора строк по шаблону с несколькими разными разделителями эффективнее регулярные выражения через COM-объект VBScript.RegExp на Windows или последовательные замены разделителей на один маркер.
Как выбрать способ
Типичные ошибки и проверка результата
Самая частая ошибка — обращение к элементу массива без проверки его существования. Строка, пришедшая из файла или от пользователя, может содержать меньше полей, чем ожидает алгоритм. Всегда проверяйте Количество() перед обращением по индексу.
Вторая группа ошибок связана с пробелами и регистром: после разбиения элементы часто содержат ведущие и конечные пробелы, которые мешают сравнению и поиску в базе. Обрабатывайте каждый элемент через СокрЛП() до использования. Третья ошибка — забытый третий параметр: при разборе CSV пустые поля теряются или, наоборот, неожиданно появляются, сдвигая структуру данных.
Как проверить результат
Совпадает с ожидаемым числом полей
Меньше или больше — проверьте разделитель и третий параметр
Значения без лишних пробелов и символов разделителя
Пробелы по краям или остатки разделителя внутри
Массив из одного пустого элемента, код не падает
Исключение или обращение за границу массива
Часто задаваемые вопросы
Как разделить строку по нескольким разным разделителям?
Замените все допустимые разделители на один маркер через последовательные вызовы СтрЗаменить(), затем разделите по этому маркеру функцией СтрРазделить(). Альтернатива — регулярные выражения через COM-объект, если конфигурация работает на Windows.
Что вернёт СтрРазделить, если разделителя в строке нет?
Массив из одного элемента — исходной строки целиком. Это безопасное поведение, но код, ожидающий несколько полей, должен проверять Количество() и корректно обрабатывать такой случай.
Как разделить строку на части фиксированной длины?
Используйте цикл с шагом, равным длине части, и функцию Сред(Строка, Позиция, Длина). СтрРазделить для этой задачи не подходит, так как работает только с разделителями.
Регистрозависима ли функция СтрРазделить?
Да, разделитель сопоставляется с учётом регистра. Если данные могут содержать разделитель в разном регистре, приведите и строку, и разделитель к одному регистру через ВРег() или НРег() перед разбиением — но учтите, что при этом изменится регистр самих данных.
Как собрать строку обратно из массива?
Функцией СтрСоединить(Массив, Разделитель). Она доступна с той же версии платформы, что и СтрРазделить, и на старых версиях заменяется циклом с конкатенацией.
Что важно запомнить
На платформе 8.3.6+ используйте СтрРазделить с явным разделителем и осознанным параметром включения пустых строк. На старых версиях — СтрЗаменить со СтрПолучитьСтроку или цикл с Найти(). Всегда проверяйте количество элементов и очищайте их через СокрЛП перед использованием.