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