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

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

Чем заменить СтрНайти в 1С: рабочие альтернативы и примеры

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

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

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

Когда вообще нужна замена СтрНайти

Прежде чем искать альтернативу, стоит определить причину. Чаще всего замена требуется в четырёх случаях: код должен работать на платформе ниже 8.3.6, нужен поиск с конца строки, требуется поиск по сложному шаблону (маске), либо поиск нужно выполнить на стороне СУБД без выгрузки данных в память.

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

Замена для старых платформ: функция Найти()

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

// Работает на любой версии платформы

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

// Позиция = 10

// Эквивалент на новых платформах

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

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

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

Поиск с конца строки и поиск N-го вхождения

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

// Поиск последнего вхождения без СтрНайти

Функция НайтиСКонца(Строка, Подстрока)

Позиция = 0;

ТекущаяПозиция = Найти(Строка, Подстрока);

Пока ТекущаяПозиция > 0 Цикл

Позиция = ТекущаяПозиция;

ТекущаяПозиция = Найти(

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

Подстрока);

Если ТекущаяПозиция > 0 Тогда

ТекущаяПозиция = Позиция + СтрДлина(Подстрока) + ТекущаяПозиция - 1;

КонецЕсли;

КонецЦикла;

Возврат Позиция;

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

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

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

Поиск по шаблону: регулярные выражения

Ни СтрНайти, ни Найти() не умеют искать по маске: например, «любые цифры», «email-адрес», «дата в формате ДД.ММ.ГГГГ». Для таких задач используются регулярные выражения. В файловых и клиент-серверных базах на Windows доступен COM-объект VBScript.RegExp.

RegExp = Новый COMОбъект("VBScript.RegExp");

RegExp.Pattern = "\d{2}\.\d{2}\.\d{4}"; // дата ДД.ММ.ГГГГ

RegExp.Global = Истина;

Результат = RegExp.Execute("Оплата от 15.03.2026 получена");

Если Результат.Count > 0 Тогда

НайденнаяДата = Результат.Item(0).Value;

КонецЕсли;

Альтернатива без COM — подключение внешней компоненты с поддержкой регулярных выражений (существуют свободно распространяемые разработки сообщества) либо перенос логики поиска в запрос к базе данных, если искомые данные хранятся в реквизитах объектов.

Поиск в данных через запрос: оператор ПОДОБНО

Если задача — найти записи справочника или документы, где строковый реквизит содержит подстроку, гораздо эффективнее выполнить поиск на стороне СУБД через оператор ПОДОБНО, а не перебирать объекты в цикле со СтрНайти.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Контрагенты.Ссылка

|ИЗ

| Справочник.Контрагенты КАК Контрагенты

|ГДЕ

| Контрагенты.Наименование ПОДОБНО &Шаблон";

Запрос.УстановитьПараметр("Шаблон", "%" + ИскомаяСтрока + "%");

Символ % в шаблоне означает любую последовательность символов, _ — один произвольный символ. Если в искомой строке могут встречаться эти символы как обычные, их нужно экранировать через СПЕЦСИМВОЛ. Поиск через запрос работает быстрее перебора и не загружает лишние данные в память, но не возвращает позицию подстроки — только факт соответствия.

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

Найти()

Любая версия платформы; только поиск с начала, без направления и номера вхождения. Считается устаревшей.

СтрНайти()

Платформа 8.3.6 и новее; направление поиска, начальная позиция, номер вхождения. Рекомендуемый вариант.

Регулярные выражения

Поиск по маске любой сложности; на Windows — через COM, кроссплатформенно — через внешние компоненты.

ПОДОБНО в запросе

Поиск по реквизитам в базе без выгрузки данных; не возвращает позицию, шаблон ограничен % и _.

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

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

// Вместо: Если СтрНайти(ИмяФайла, "Отчет_") = 1 Тогда

Если СтрНачинаетсяС(ИмяФайла, "Отчет_") Тогда

// ...

КонецЕсли;

// Вместо поиска расширения с конца

Если СтрЗаканчиваетсяНа(НРег(ИмяФайла), ".xml") Тогда

// ...

КонецЕсли;

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

Типичные ошибки при замене СтрНайти
01
Сравнение результата с 1 для проверки вхождения — правильно проверять на <> 0: подстрока может находиться в любой позиции.
02
Игнорирование регистра — поиск «Артикул» не найдёт «артикул»; приводите обе строки к одному регистру.
03
Использование COM-регулярок в серверном коде на Linux — вызов падает с ошибкой создания объекта.
04
Перебор объектов в цикле со СтрНайти вместо запроса с ПОДОБНО — на больших таблицах это в разы медленнее.
05
Передача в ПОДОБНО строки без экранирования % и _ — шаблон срабатывает на лишние записи.

Как выбрать подходящий вариант

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

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

Маршрут решения

Как выбрать действие

Платформа 8.3.6+, простой поиск позицииИспользуйте СтрНайти — замена не требуется
Код должен работать на платформе ниже 8.3.6Используйте Найти() и циклы для поиска с конца
Нужен поиск по шаблону (цифры, даты, email)Регулярные выражения: COM на Windows или внешняя компонента
Поиск по реквизитам объектов в базеЗапрос с оператором ПОДОБНО и параметром-шаблоном
Проверка префикса или суффикса строкиСтрНачинаетсяС / СтрЗаканчиваетсяНа вместо СтрНайти

Проверка результата после замены

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

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

Итог

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

Для старых платформ замена СтрНайти — функция Найти() с циклами для сложных случаев. Для шаблонов — регулярные выражения, для поиска по базе — ПОДОБНО в запросе, для префиксов и суффиксов — СтрНачинаетсяС и СтрЗаканчиваетсяНа. Всегда учитывайте регистр и проверяйте граничные случаи.

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

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

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

Как искать подстроку без учёта регистра?

Приведите обе строки к одному регистру: СтрНайти(НРег(Строка), НРег(Подстрока)). Учтите, что возвращённая позиция останется корректной, так как смена регистра не меняет длину строки.

Работают ли регулярные выражения в тонком и веб-клиенте?

COM-объект VBScript.RegExp доступен только в толстом и тонком клиенте на Windows. В веб-клиенте и на Linux-сервере он недоступен — используйте внешние компоненты или выполняйте поиск на стороне СУБД.

Как найти все вхождения подстроки в строку?

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

Можно ли использовать ПОДОБНО для поиска позиции подстроки?

Нет. ПОДОБНО только проверяет соответствие строки шаблону и не возвращает позицию. Если позиция нужна — выберите записи запросом, а затем примените СтрНайти к полученным значениям.

Почему СтрНайти возвращает 0, хотя подстрока точно есть?

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