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