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

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

Как найти слово в строке в 1С: поиск подстроки на встроенном языке

Как найти слово или подстроку в строке в 1С: функции СтрНайти, Найти, СтрЧислоВхождений, поиск без учёта регистра и разбор типичных ошибок с примерами кода.

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

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

Важный нюанс: поиск в 1С по умолчанию чувствителен к регистру. Строка «Склад» не будет найдена в тексте «складской учёт» без предварительного приведения обеих строк к одному регистру через ВРег() или НРег(). Это самая частая причина «неработающего» поиска.

Функция СтрНайти: синтаксис и базовый пример

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

Строка = "Поступление товаров и услуг № 145";

Позиция = СтрНайти(Строка, "товаров");

// Позиция = 13

Если Позиция > 0 Тогда

Сообщить("Слово найдено, начинается с символа " + Позиция);

Иначе

Сообщить("Слово не найдено");

КонецЕсли;

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

Проверку «содержит ли строка слово» принято записывать компактно: Если СтрНайти(НРег(Наименование), НРег("скидка")) > 0 Тогда. Такой вариант одновременно решает проблему регистра.

bsl
Позиция = СтрНайти(НРег(НаименованиеТовара), НРег("кабель"));
Если Позиция > 0 Тогда
    // слово найдено
КонецЕсли;

Функция Найти для старых конфигураций

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

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

Поиск без учёта регистра и с учётом направления

Чтобы найти слово независимо от того, как оно написано, приведите обе строки к одному регистру. Чаще используют НРег(), поскольку буква «ё» и некоторые спецсимволы корректнее обрабатываются в нижнем регистре, хотя на практике разницы между НРег и ВРег для этой задачи нет:

ИскомоеСлово = "Счёт";

ТекстДокумента = "выставлен счёт-фактура от 12.03";

Если СтрНайти(НРег(ТекстДокумента), НРег(ИскомоеСлово)) > 0 Тогда

// совпадение найдено

КонецЕсли;

Третий параметр СтрНайти — НаправлениеПоиска — позволяет искать с конца строки: СтрНайти(Строка, "/", НаправлениеПоиска.СКонца). Это удобно, когда нужно отсечь расширение файла или последний элемент пути. Четвёртый параметр задаёт позицию, с которой начинать поиск, а пятый — номер вхождения: например, найти вторую запятую в строке CSV.

Как найти все вхождения и посчитать их количество

Когда нужно не просто проверить наличие слова, а узнать, сколько раз оно встречается, используйте СтрЧислоВхождений(Строка, Подстрока). Функция вернёт целое число — количество непересекающихся вхождений:

Текст = "товар;товар;услуга;товар";

Количество = СтрЧислоВхождений(Текст, "товар"); // 3

Если требуется обработать каждое вхождение по отдельности — например, извлечь текст между повторяющимися разделителями — удобнее цикл со смещением начальной позиции либо разбиение строки через СтрРазделить(), которая вернёт массив частей. Для сложных шаблонов (цифры, маски, необязательные символы) простого поиска недостаточно — там применяют регулярные выражения через COM-объект VBScript.RegExp на Windows-сервере или внешние компоненты.

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

СтрНайти

Основной вариант: позиция вхождения, направление, номер вхождения. Не подходит для масок и шаблонов.

Найти

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

СтрЧислоВхождений

Когда нужно количество повторов слова, а не позиция.

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

Когда строка состоит из элементов с разделителем и нужно проверить каждый элемент отдельно.

Поиск слова в запросе: ГДЕ Наименование ПОДОБНО

Отдельный сценарий — поиск подстроки не в коде, а при выборке данных из базы. В языке запросов 1С для этого служит оператор ПОДОБНО с символом процента в качестве маски:

ВЫБРАТЬ

Номенклатура.Ссылка

ИЗ

Справочник.Номенклатура КАК Номенклатура

ГДЕ

Номенклатура.Наименование ПОДОБНО "%кабель%"

Конструкция "%слово%" означает: любые символы до и после искомого фрагмента. Учтите, что такой запрос не использует индексы эффективно — на больших таблицах выборка с начальным символом % выполняется полным сканированием и может заметно нагружать сервер. Для массового поиска по тексту в крупных базах лучше включать полнотекстовый поиск данных, который работает через отдельный индекс и поддерживает морфологию.

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

Первая ошибка — забыть про регистр и удивляться, почему «не находит» очевидное слово. Вторая — сравнивать результат СтрНайти с Неопределено или NULL: функция возвращает число, и корректная проверка — > 0. Третья — искать слово с лишними пробелами: пользовательский ввод часто содержит пробелы по краям, поэтому перед поиском применяйте СокрЛП() к обеим строкам.

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

Типичные ошибки
01
Поиск без приведения регистра — слово «Счёт» не находится в тексте «счёт-фактура»
02
Проверка результата на NULL вместо сравнения с нулём — условие ведёт себя непредсказуемо
03
Поиск слова без СокрЛП — лишний пробел в пользовательском вводе даёт ложный отрицательный результат
04
Ожидание поиска целого слова — СтрНайти ищет подстроку и срабатывает на части слов

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

Чтобы убедиться, что поиск работает правильно, выведите промежуточные значения через Сообщить() или используйте отладчик конфигуратора с точкой останова на строке вызова. В окне «Вычислить выражение» (Shift+F9) удобно проверить, что реально содержится в переменной: часто там оказываются неразрывные пробелы, переносы строк (символы Символы.ПС) или данные не строкового типа.

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

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

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

Возвращаемое значение
Норма

Число от 1 и выше — позиция вхождения

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

0 — подстрока не найдена, проверьте регистр и пробелы

Содержимое переменной в отладчике
Норма

Виден ожидаемый текст без лишних символов

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

Неразрывные пробелы, переносы строк, тип не «Строка»

Границы слова
Норма

Найдено именно слово, окружённое разделителями

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

Срабатывание на части другого слова

FAQ: частые вопросы о поиске в строке

Чем СтрНайти отличается от Найти?

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

Как проверить, что строка начинается с определённого слова?

Сравните результат СтрНайти с единицей: если функция вернула 1, подстрока находится в самом начале. Альтернатива — взять левую часть строки через Лев(Строка, СтрДлина(Слово)) и сравнить её с искомым словом, предварительно приведя обе части к одному регистру.

Почему СтрНайти не находит слово, которое точно есть в строке?

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

Как найти второе или третье вхождение слова?

Передайте номер вхождения пятым параметром: СтрНайти(Строка, "слово", , , 2) найдёт второе вхождение. Если нужна позиция относительно уже найденной, укажите начальную позицию четвёртым параметром, сместив её на длину предыдущего вхождения.

Можно ли искать по шаблону, например «любые цифры»?

СтрНайти ищет только точную подстроку. Для шаблонов в запросах используйте ПОДОБНО с символами % и _, а в коде на Windows — регулярные выражения через COM-объект VBScript.RegExp. В файловых и мобильных вариантах без COM придётся реализовывать разбор вручную посимвольно.

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

СтрНайти работает со всей строкой целиком, включая символы переноса, поэтому искать можно сразу по всему тексту. Если нужно знать, в какой именно строке найдено слово, разбейте текст через СтрРазделить по символу Символы.ПС и проверяйте каждый элемент массива в цикле.

Итог

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

Основной инструмент поиска подстроки в 1С — СтрНайти: она возвращает позицию вхождения или 0. В старых конфигурациях используйте Найти, в запросах — ПОДОБНО с маской %...%. Всегда учитывайте регистр, пробелы и тип данных, а для больших таблиц избегайте поиска по маске без индекса.