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