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