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

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

Сколько слов в строке 1С: способы подсчёта с примерами кода

Как посчитать количество слов в строке в 1С: разбор по разделителям, функция СтрРазделить, цикл с пробелами, готовые примеры кода для 8.3 и типичные ошибки.

Задача подсчёта слов в строке встречается в 1С чаще, чем кажется: разбор ФИО на части, проверка заполненности полей, обработка адресов, импорт данных из текстовых файлов и Excel. Встроенной функции «количество слов» во встроенном языке 1С нет, поэтому разработчику приходится выбирать один из рабочих приёмов: разделение строки по разделителю, посимвольный перебор или использование регулярных выражений через внешние компоненты.

Выбор способа зависит от версии платформы, характера данных и требований к производительности. Для строк, где слова гарантированно разделены одиночными пробелами, достаточно простого цикла. Для «грязных» данных с двойными пробелами, табуляциями и переносами строк нужен более устойчивый алгоритм, иначе подсчёт даст завышенный результат.

Как 1С понимает «слово» и почему это важно

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

Если строка содержит фразу «Иванов Иван» с двумя пробелами, наивный подсчёт пробелов плюс один даст три «слова» вместо двух. Аналогично адрес «г. Москва,ул. Ленина» без пробела после запятой может быть посчитан как одно слово. Поэтому надёжный алгоритм сначала нормализует строку, а потом считает фрагменты.

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

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

Функция КоличествоСлов(Строка)

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

Возврат МассивСлов.Количество();

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

Третий параметр, равный Ложь, критически важен: он указывает не включать пустые элементы в результат. Без него строка с двойными пробелами породит пустые элементы массива, и подсчёт окажется завышенным. СокрЛП в начале убирает ведущие и завершающие пробелы, которые тоже могли бы исказить результат на старых приёмах.

Если слова могут разделяться не только пробелами, но и запятыми или точками с запятой, сначала замените все разделители на пробел через СтрЗаменить, а затем применяйте СтрРазделить. Это проще и быстрее, чем посимвольный разбор.

bsl
Строка = СтрЗаменить(Строка, ",", " ");
Строка = СтрЗаменить(Строка, ";", " ");
Строка = СтрЗаменить(Строка, Символы.Таб, " ");
КоличествоСлов = СтрРазделить(СокрЛП(Строка), " ", Ложь).Количество();

Способ 2: посимвольный цикл для старых платформ

На платформах старше 8.3.6 функции СтрРазделить нет, поэтому используют классический цикл: идём по символам и считаем моменты, когда заканчивается слово. Признак конца слова — разделитель после непустой последовательности символов.

Функция КоличествоСловЦиклом(Строка)

Счетчик = 0;

ВСлове = Ложь;

Для Поз = 1 По СтрДлина(Строка) Цикл

Символ = Сред(Строка, Поз, 1);

Если Символ = " " Или Символ = Символы.Таб Тогда

ВСлове = Ложь;

Иначе

Если Не ВСлове Тогда

Счетчик = Счетчик + 1;

ВСлове = Истина;

КонецЕсли;

КонецЕсли;

КонецЦикла;

Возврат Счетчик;

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

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

Способ 3: подсчёт через замену и длину строки

Компактный трюк для «чистых» данных: количество слов равно количеству пробелов плюс один. Чтобы найти количество пробелов, сравнивают длину строки до и после удаления пробелов через СтрЗаменить.

СтрокаБезПробелов = СтрЗаменить(Строка, " ", "");

КоличествоСлов = СтрДлина(Строка) - СтрДлина(СтрокаБезПробелов) + 1;

Метод работает только при строгом условии: слова разделены ровно одним пробелом, нет пробелов по краям. Перед применением обязательно выполните СокрЛП. Для данных из справочников, где пользователь мог ввести лишние пробелы, способ не подходит — используйте СтрРазделить.

Сравнение способов

СтрРазделить

Оптимален для платформы 8.3.6 и новее; устойчив к двойным пробелам; ограничение — один тип разделителя за вызов

Посимвольный цикл

Подходит для любых версий платформы и сложных наборов разделителей; медленнее на больших текстах

Подсчёт пробелов + 1

Самый короткий код; применим только к нормализованным строкам с одиночными пробелами

Обработка нестандартных разделителей и «грязных» данных

Реальные данные из Excel, CSV или веб-форм часто содержат неразрывный пробел (код 160), который визуально неотличим от обычного, но СтрРазделить с разделителем « » его не увидит. Симптом: функция возвращает одно слово там, где их явно несколько. Лечится предварительной заменой: СтрЗаменить(Строка, Символ(160), " ").

Переносы строк внутри многострочного текста тоже являются разделителями слов. Перед подсчётом замените Символы.ПС и Символы.ВК на пробелы, иначе последнее слово одной строки и первое слово следующей склеятся в одно. Аналогично поступают с табуляцией.

Порядок подготовки строки к подсчёту
  1. 1
    Замените Символ(160) на обычный пробел
  2. 2
    Замените табуляции и переносы строк на пробелы
  3. 3
    Замените знаки препинания-разделители (запятые, точки с запятой) на пробелы при необходимости
  4. 4
    Выполните СокрЛП
  5. 5
    Вызовите СтрРазделить с параметром Ложь и возьмите Количество() массива

Практические сценарии применения

Разбор ФИО на части

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

Проверка заполненности полей

При обмене с контрагентами иногда требуется, чтобы наименование содержало не менее двух слов или чтобы поле комментария не было односимвольным «проходным» значением. Подсчёт слов через СтрРазделить — простой способ формализовать такую проверку в процедуре ОбработкаПроверкиЗаполнения.

Импорт текстовых данных

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

Типичные ошибки
01
Вызов СтрРазделить без третьего параметра — двойные пробелы дают пустые элементы и завышенный счёт
02
Забытый СокрЛП — краевые пробелы искажают результат при подсчёте через количество пробелов
03
Игнорирование неразрывного пробела Символ(160) — строка визуально из нескольких слов считается одним словом
04
Использование приёма «пробелы плюс один» на ненормализованных данных из пользовательского ввода
05
Подсчёт слов в многострочном тексте без замены переносов строк — склейка слов на стыке строк

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

После внедрения функции проверьте её на контрольном наборе: пустая строка (ожидается 0), строка из одних пробелов (0), одно слово (1), фраза с двойными и тройными пробелами, текст с табуляциями и переносами, строка с неразрывными пробелами. Если все случаи дают ожидаемые числа, алгоритм готов к работе.

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

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

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

Пустая строка или строка из пробелов
Норма

Функция возвращает 0

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

Возвращает 1 или вызывает ошибку

Фраза с двойными пробелами
Норма

Счёт равен числу реальных слов

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

Счёт завышен на количество лишних пробелов

Текст с неразрывными пробелами
Норма

Слова распознаются корректно

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

Вся строка считается одним словом

Многострочный текст
Норма

Слова на стыках строк считаются раздельно

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

Слова на стыке склеиваются в одно

Ограничения и альтернативы

Все описанные способы считают слова формально — по разделителям. Они не понимают переносы по слогам, дефисные конструкции и аббревиатуры с точками. Если требуется лингвистический подсчёт, близкий к тому, что делает Word, встроенных средств 1С недостаточно; придётся либо договариваться о формальном определении слова с постановщиком задачи, либо использовать внешние компоненты с регулярными выражениями.

Для работы с регулярными выражениями в файловом режиме на Windows иногда применяют COM-объект VBScript.RegExp, где шаблон вида «\S+» находит все непробельные последовательности. Это рабочий, но платформенно-зависимый путь: на Linux-сервере и в веб-клиенте COM недоступен, поэтому для кроссплатформенных решений надёжнее оставаться на СтрРазделить и циклах.

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

Есть ли в 1С готовая функция подсчёта слов?

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

Почему СтрРазделить возвращает больше элементов, чем слов?

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

Как посчитать слова, если разделителей несколько?

Приведите все разделители к одному виду: последовательно замените запятые, точки с запятой, табуляции и переносы строк на обычный пробел через СтрЗаменить, а затем вызовите СтрРазделить с разделителем-пробелом и параметром Ложь.

Как обработать неразрывный пробел при подсчёте?

Неразрывный пробел — это Символ(160), и обычный разделитель его не распознаёт. Перед подсчётом выполните замену: Строка = СтрЗаменить(Строка, Символ(160), " "). После этого строка обрабатывается стандартно.

Что быстрее: СтрРазделить или цикл по символам?

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

Как посчитать слова в многострочном тексте?

Сначала замените символы переноса строки (Символы.ПС) и возврата каретки (Символы.ВК) на пробелы, затем примените обычный алгоритм подсчёта. Без замены последнее слово строки и первое слово следующей сольются в одно.

Итог

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

Оптимальный способ посчитать слова в строке 1С — СтрРазделить с параметром Ложь и методом Количество(). Перед подсчётом нормализуйте строку: уберите краевые пробелы, замените неразрывные пробелы, табуляции и переносы строк. Для платформ старше 8.3.6 используйте посимвольный цикл с флагом нахождения внутри слова.