К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как разделить строку по разделителю в 1С

Разбираем, как разделить строку по разделителю в 1С: СтрРазделить, СтрНайти, СтрЗаменить, работа с многострочными текстами, типичные ошибки и готовые примеры кода.

Разделение строки по разделителю — одна из самых частых задач во встроенном языке 1С: разбор CSV-файлов, обработка списков значений, парсинг ответов веб-сервисов, разделение ФИО или составных артикулов. В зависимости от версии платформы и характера данных задача решается по-разному: встроенной функцией СтрРазделить, функциями поиска СтрНайти и Сред или объектом ТекстовыйДокумент для многострочных данных.

Основной инструмент в современных версиях платформы (начиная с 8.3.6) — функция СтрРазделить, которая возвращает массив подстрок. Для старых версий платформы или нестандартных сценариев используют классический цикл с поиском позиции разделителя. Ниже разобраны оба подхода, их ограничения и готовые примеры кода, которые можно перенести в свой модуль без доработки.

При выборе способа важно учитывать три фактора: версию платформы, наличие пустых элементов между разделителями и вложенность разделителей (когда часть строки сама содержит символ-разделитель, например запятую внутри кавычек в CSV). Именно эти нюансы чаще всего становятся причиной ошибок при загрузке данных.

Функция СтрРазделить — основной способ

Функция СтрРазделить(Строка, Разделитель, ВключатьПустые) разбивает строку на массив подстрок. Первый параметр — исходная строка, второй — разделитель (может состоять из нескольких символов, тогда каждый из них считается разделителем), третий — необязательный признак включения пустых элементов в результат.

Пример простого использования:

Строка = "Иванов;Петров;Сидоров";

Массив = СтрРазделить(Строка, ";");

// Массив[0] = "Иванов", Массив[1] = "Петров", Массив[2] = "Сидоров"

Если разделитель задать как строку из нескольких символов, например СтрРазделить(Строка, ";,"), то разделение будет выполняться и по точке с запятой, и по запятой. Это удобно, когда формат входных данных не стабилен и встречаются разные варианты записи.

Обратите внимание: СтрРазделить не умеет трактовать многосимвольную последовательность как единый разделитель. Строка "::" будет восприниматься как один символ «двоеточие», а не как пара. Если нужен именно многосимвольный разделитель, сначала замените его на одиночный символ через СтрЗаменить.

Обработка пустых элементов между разделителями

Частая ситуация: строка вида "100;;300" содержит пустое значение между разделителями. По умолчанию СтрРазделить включает пустые элементы в массив, и это правильно для позиционных форматов, где номер элемента соответствует номеру колонки. Если передать третьим параметром Ложь, пустые элементы будут отброшены.

Строка = "100;;300";

А = СтрРазделить(Строка, ";"); // 3 элемента: "100", "", "300"

Б = СтрРазделить(Строка, ";", Ложь); // 2 элемента: "100", "300"

Отбрасывать пустые элементы безопасно только тогда, когда порядок и позиция значений не имеют смысла — например, при разборе списка тегов. При разборе табличных данных (CSV, выгрузки из Excel) пустые элементы отбрасывать нельзя: сместятся номера колонок, и данные попадут не в те поля.

Разделение строки в старых версиях платформы

Если платформа ниже 8.3.6 или режим совместимости запрещает СтрРазделить, используется классический алгоритм на основе СтрНайти и Сред. Суть: в цикле ищется позиция разделителя, подстрока до него добавляется в массив, обработанная часть отсекается.

Функция РазделитьСтроку(Строка, Разделитель)

Массив = Новый Массив;

Позиция = СтрНайти(Строка, Разделитель);

Пока Позиция > 0 Цикл

Массив.Добавить(Лев(Строка, Позиция - 1));

Строка = Сред(Строка, Позиция + СтрДлина(Разделитель));

Позиция = СтрНайти(Строка, Разделитель);

КонецЦикла;

Массив.Добавить(Строка);

Возврат Массив;

КонецФункции

Такой подход поддерживает многосимвольные разделители «из коробки» и работает на любой версии платформы. Его минус — больше кода и необходимость аккуратно следить за отсечением обработанной части, иначе цикл станет бесконечным.

Ещё один приём для старых версий — заменить разделитель на символ переноса строки через СтрЗаменить и затем перебрать строки через СтрЧислоСтрок и СтрПолучитьСтроку. Способ рабочий, но опасен, если исходный текст уже содержит переносы строк: границы элементов собьются.

Порядок действий
  1. 1
    Определите версию платформы и режим совместимости конфигурации
  2. 2
    Если доступна СтрРазделить — используйте её, иначе напишите функцию на СтрНайти и Сред
  3. 3
    Решите, нужны ли пустые элементы, исходя из формата данных
  4. 4
    Проверьте результат на тестовой строке с пустыми значениями и разделителем на конце
  5. 5
    Добавьте контроль количества элементов перед записью данных в базу

Разбор CSV и строк с вложенными разделителями

Стандартная проблема CSV: значение внутри кавычек само содержит запятую, например "Иванов, И.И.";5000. Простое разделение по запятой или точке с запятой разорвёт такое значение на части. СтрРазделить не понимает кавычки-экраны, поэтому для полноценного CSV нужен посимвольный разбор с учётом состояния «внутри кавычек».

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

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

Перед разбором файла из внешнего источника выведите первые две-три строки в сообщение или журнал и посмотрите на них глазами: какой реально используется разделитель, есть ли кавычки, есть ли заголовок колонок. Это занимает минуту и избавляет от отладки вслепую.
ПЗ
Практическое замечание

Проверка результата разделения

После разделения всегда проверяйте три вещи: количество элементов массива, отсутствие неожиданных пробелов по краям значений и корректность последнего элемента. Строка, заканчивающаяся разделителем ("а;б;"), даст последним элементом пустую строку — это нормально, но об этом нужно помнить при обращении по индексу.

Значения из текстовых файлов часто содержат пробелы, неразрывные пробелы (Символ(160)) и служебные символы. Перед использованием применяйте СокрЛП к каждому элементу, а при необходимости — замену неразрывного пробела на обычный или удаление. Числа дополнительно пропускайте через приведение типа с обработкой исключения, иначе строка "1 200,50" с неразрывным пробелом вызовет ошибку преобразования.

Контрольные точки

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

Количество элементов массива
Норма

Совпадает с ожидаемым числом колонок

Тревожный признак

Меньше или больше — сбит разделитель или есть вложенные разделители

Крайние значения
Норма

Без пробелов и служебных символов после СокрЛП

Тревожный признак

Остаются невидимые символы — нужна замена Символ(160)

Пустые элементы
Норма

Присутствуют там, где колонка реально пуста

Тревожный признак

Пустые значения в колонках, которые должны быть заполнены

Типичные ошибки при разделении строк

Самая распространённая ошибка — обращение к элементу массива по индексу без проверки его существования. Если входная строка пришла пустой или в неожиданном формате, обращение Массив[1] вызовет ошибку «Индекс находится за границами массива». Всегда проверяйте Массив.Количество() перед обращением.

Вторая ошибка — путаница между СтрРазделить и обратной операцией СтрСоединить: первая разбирает строку в массив, вторая собирает массив в строку с указанным разделителем. Третья — попытка использовать многосимвольный разделитель напрямую в СтрРазделить, где каждый символ трактуется отдельно.

Типичные ошибки
01
Обращение к элементу массива без проверки количества — ошибка индекса на нештатных данных
02
Отключение пустых элементов при разборе позиционных форматов — смещение данных по колонкам
03
Ожидание, что СтрРазделить воспримет ";;" как единый разделитель — каждый символ считается разделителем
04
Игнорирование неразрывных пробелов — ошибки преобразования чисел и ложные несовпадения при сравнении

Частые вопросы

Как разделить строку по нескольким разным разделителям одновременно?

Передайте их одной строкой во второй параметр: СтрРазделить(Строка, ";,") разделит и по точке с запятой, и по запятой. Учтите, что каждый символ работает как отдельный разделитель, многосимвольные последовательности так не задаются.

Как собрать массив обратно в строку с разделителем?

Используйте функцию СтрСоединить(Массив, ";") — она вернёт строку, где элементы массива склеены указанным разделителем. Это обратная операция к СтрРазделить.

Что делать, если разделитель состоит из нескольких символов, например "||"?

Сначала замените его на одиночный редкий символ через СтрЗаменить, затем разделите по нему. Либо используйте цикл со СтрНайти и Сред — он корректно работает с многосимвольными разделителями.

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

Чаще всего в значении есть неразрывный пробел (Символ(160)) или пробелы-разделители разрядов. Примените СокрЛП и замену неразрывного пробела, а преобразование выполняйте через попытку/исключение или проверку содержимого строки.

Как разделить многострочный текст на отдельные строки?

Используйте СтрЧислоСтрок и СтрПолучитьСтроку в цикле либо объект ТекстовыйДокумент. Для больших файлов ТекстовыйДокумент предпочтительнее — он читает данные построчно и не загружает весь текст в память.

СтрРазделить недоступна — в чём причина?

Функция появилась в платформе 8.3.6. Если она недоступна, проверьте версию платформы и режим совместимости конфигурации в её свойствах. Для старых режимов используйте функцию на основе СтрНайти и Сред.

Итог

Что важно запомнить

Основной инструмент — СтрРазделить, возвращающая массив подстрок; для старых платформ — цикл со СтрНайти и Сред. Сохраняйте пустые элементы в позиционных форматах, проверяйте количество элементов перед обращением по индексу и очищайте значения от неразрывных пробелов перед преобразованием.