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

Особенность поиска в заключается в том, что здесь нет универсального оператора как LIKE в SQL. Вместо этого используются специализированные функции, каждая из которых имеет свои нюансы. Мы покажем, когда лучше применять СОДЕРЖИТ, а когда — ПОДСТРОКА, как учитывать регистр и почему иногда проще перенести логику в программный код. Все примеры приведены для актуальных версий платформы 1С:Предприятие 8.3.

1. Функция СОДЕРЖИТ: базовый поиск подстроки

Самый простой и интуитивно понятный способ — использовать функцию СОДЕРЖИТ. Она проверяет, содержится ли одна строка внутри другой, и возвращает булево значение (ИСТИНА/ЛОЖЬ). Синтаксис минималистичен:

ГДЕ СОДЕРЖИТ(Поле, "искомая подстрока")

Пример запроса, который найдет всех контрагентов с названием, содержащим слово "торг":

ВЫБРАТЬ

Наименование

ИЗ

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

ГДЕ

СОДЕРЖИТ(Наименование, "торг")

  • ✅ Простота использования — идеально для быстрых проверок
  • ✅ Работает во всех версиях 1С 8.x
  • ⚠️ Чувствительна к регистру (если не указан параметр нечувствительности)
  • ⚠️ Не поддерживает шаблоны с подстановочными знаками

Важный нюанс: по умолчанию поиск регистрозависимый. Чтобы игнорировать регистр, добавьте третий параметр:

СОДЕРЖИТ(Поле, "Подстрока", Ложь)  // Ложь = игнорировать регистр
💡

Если вам нужно найти подстроку в начале или конце строки, комбинируйте СОДЕРЖИТ с функциями ЛЕВ или ПРАВ. Например: СОДЕРЖИТ(ЛЕВ(Поле, 5), "АБВ") проверит первые 5 символов.

2. Функция ПОДСТРОКА: извлечение фрагмента по позиции

Когда требуется не просто проверить наличие подстроки, а извлечь ее или работать с конкретными позициями в строке, на помощь приходит ПОДСТРОКА. Она возвращает часть строки, начиная с указанной позиции и заданной длины:

ПОДСТРОКА(Строка, НачальнаяПозиция, Длина)

Классический пример — извлечение префикса номера документа:

ВЫБРАТЬ

Номер,

ПОДСТРОКА(Номер, 1, 3) КАК Префикс

ИЗ

Документ.ЗаказПокупателя

Параметр Описание Пример
Строка Исходная строка для обработки "АБВГД-12345"
НачальнаяПозиция Позиция первого символа (начиная с 1) 4 (символ "Г")
Длина Количество возвращаемых символов 2 (вернет "ГД")

Совмещая ПОДСТРОКА с НАЙТИ (аналог ПОИСК в программном коде), можно реализовать сложную логику поиска. Например, извлечь все символы между двумя разделителями:

ВЫБРАТЬ

ПОДСТРОКА(

Поле,

НАЙТИ(Поле, "-") + 1,

НАЙТИ(Поле, "_") - НАЙТИ(Поле, "-") - 1

) КАК КодИзделия

ИЗ ...

Чем отличается НАЙТИ от ПОИСК?

В запросах 1С функция НАЙТИ аналогична программной функции ПОИСК — обе возвращают позицию подстроки в строке. Однако в программном коде ПОИСК имеет дополнительный параметр для указания направления поиска (с начала или конца строки), чего нет в запросах.

3. Функция ПОИСК: определение позиции подстроки

Если вам нужно не только найти подстроку, но и узнать ее точное положение в строке, используйте ПОИСК. Эта функция возвращает номер позиции первого вхождения подстроки (или 0, если подстрока не найдена):

ПОИСК(ИскомаяПодстрока, Строка)

Практический пример — поиск документов, где номер содержит дефис не в стандартной позиции:

ВЫБРАТЬ

Номер КАК Документ,

ПОИСК(Номер, "-") КАК ПозицияДефиса

ИЗ

Документ.РеализацияТоваровУслуг

ГДЕ

ПОИСК(Номер, "-") <> 4 // Дефис не на 4-й позиции

⚠️ Внимание: Функция ПОИСК в запросах 1С всегда регистрозависима. Для регистронезависимого поиска предварительно преобразуйте строку с помощью ВРЕГ (в верхний регистр) или НРЕГ (в нижний регистр).

Комбинация ПОИСК с ПОДСТРОКА позволяет реализовать аналог функции МЕЖДУ из SQL. Например, чтобы извлечь текст между двумя маркерами:

ВЫБРАТЬ

ПОДСТРОКА(

Комментарий,

ПОИСК(Комментарий, "[") + 1,

ПОИСК(Комментарий, "]") - ПОИСК(Комментарий, "[") - 1

) КАК Тэг

ИЗ

Документ.ЗаказПокупателя

ГДЕ

ПОИСК(Комментарий, "[") > 0

И ПОИСК(Комментарий, "]") > ПОИСК(Комментарий, "[")

📊 Какой способ поиска подстроки вы используете чаще?
СОДЕРЖИТ
ПОДСТРОКА
ПОИСК
Регулярные выражения
Другой

4. Регулярные выражения: мощный инструмент для сложных шаблонов

Для задач, где стандартные функции не справляются (поиск по шаблону, проверка форматов, извлечение данных по сложным правилам), в 1С 8.3.14+ появилась поддержка регулярных выражений прямо в запросах. Это открывает возможности, сравнимые с REGEXP в SQL.

Базовый синтаксис:

РЕГВЫР(Строка, Шаблон)

Примеры применения:

  • 🔍 Поиск email-адресов: РЕГВЫР(Комментарий, "[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}")
  • 📄 Проверка форматов документов: РЕГВЫР(Номер, "^[А-Я]{2}-\d{4}/[А-Я]{3}$") для формата "АБ-1234/ВГД"
  • 📊 Извлечение чисел из текста: РЕГВЫРЗАМ(Описание, "\d+", "") (заменит все числа на пустую строку)

Важное ограничение: регулярные выражения в запросах 1С поддерживают не все возможности PCRE. Например, здесь нет ленивых квантификаторов и некоторых утверждений (lookbehind). Для сложных случаев лучше перенести логику в программный код с использованием объекта РегулярноеВыражение.

Пример запроса, который найдет все документы с номерами телефонов в комментариях:

ВЫБРАТЬ

Номер,

Комментарий

ИЗ

Документ.ЗаказПокупателя

ГДЕ

РЕГВЫР(Комментарий, "(\+7|8)[\s-]?\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{2}[\s-]?\d{2}")

Тестируйте шаблон на сайте regex101.com|Проверьте версию платформы (нужна 8.3.14+)|Упростите шаблон — не все возможности PCRE поддерживаются|Для сложных случаев переносите логику в программный код-->

5. Поиск с использованием ПОДОБНО (аналог LIKE в SQL)

В версиях 1С:Предприятие 8.3.15+ появился оператор ПОДОБНО, который работает аналогично LIKE в SQL. Это удобно для поиска по шаблонам с подстановочными знаками:

  • % — любая последовательность символов (включая пустую)
  • _ — ровно один любой символ

Примеры:

// Найти строки, начинающиеся на "АБ"

ГДЕ Поле ПОДОБНО "АБ%"

// Найти строки с "123" в любой позиции

ГДЕ Поле ПОДОБНО "%123%"

// Найти строки длиной ровно 5 символов, где 3-й символ "X"

ГДЕ Поле ПОДОБНО "__X__"

Оператор ПОДОБНО поддерживает экранирование специальных символов с помощью \. Например, чтобы найти строку с реальным символом %, используйте:

ГДЕ Поле ПОДОБНО "50\%"
⚠️ Внимание: В отличие от SQL, в 1С оператор ПОДОБНО по умолчанию регистрочувствителен. Для регистронезависимого поиска преобразуйте строку с помощью ВРЕГ:

ГДЕ ВРЕГ(Поле) ПОДОБНО ВРЕГ("аб%")

6. Оптимизация производительности: когда переносить логику в код

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

  • 🐢 Сложные регулярные выражения, которые тормозят выполнение запроса
  • 🔄 Многоступенчатая обработка строк (например, несколько вложенных ПОДСТРОКА)
  • 📊 Необходимость агрегирования результатов поиска (подсчет вхождений, группировка)

Пример оптимизации: вместо запроса с несколькими СОДЕРЖИТ:

// НЕОПТИМАЛЬНО

ВЫБРАТЬ

Наименование

ИЗ

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

ГДЕ

СОДЕРЖИТ(Наименование, "красный")

ИЛИ СОДЕРЖИТ(Наименование, "синий")

ИЛИ СОДЕРЖИТ(Наименование, "зеленый")

Лучше использовать программный код:

Цвета = Новый Массив;

Цвета.Добавить("красный");

Цвета.Добавить("синий");

Цвета.Добавить("зеленый");

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

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

"ВЫБРАТЬ

| Наименование

|ИЗ

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

|ГДЕ

| &ФильтрПоЦветам";

Запрос.УстановитьПараметр("ФильтрПоЦветам", Новый ОписаниеТипов("Строка", Цвета));

Результат = Запрос.Выполнить();

Критерий выбора: если логика поиска требует более 3-4 вложенных функций или обработки каждого символа строки, переносите ее в программный код. Это ускорит выполнение и упростит поддержку.

💡

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

7. Практические примеры: решения реальных задач

Разберем типичные бизнес-задачи и их решение с поиском подстрок.

Задача 1. Найти все заказы, где в комментарии указано "срочно" или "приоритет":

ВЫБРАТЬ

Номер,

Дата,

Комментарий

ИЗ

Документ.ЗаказПокупателя

ГДЕ

СОДЕРЖИТ(НРЕГ(Комментарий), "срочно")

ИЛИ СОДЕРЖИТ(НРЕГ(Комментарий), "приоритет")

Задача 2. Извлечь артикулы из наименований номенклатуры (формат "Название [АРТ12345]"):

ВЫБРАТЬ

Наименование,

ПОДСТРОКА(

Наименование,

ПОИСК(Наименование, "[") + 1,

ПОИСК(Наименование, "]") - ПОИСК(Наименование, "[") - 1

) КАК Артикул

ИЗ

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

ГДЕ

ПОИСК(Наименование, "[") > 0

Задача 3. Проверить корректность ИНН контрагентов (10 или 12 цифр):

ВЫБРАТЬ

Наименование,

ИНН

ИЗ

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

ГДЕ

РЕГВЫР(ИНН, "^\d{10}$|^\d{12}$")

Задача 4. Найти документы с номерами, не соответствующими шаблону "ААА-000000":

ВЫБРАТЬ

Номер

ИЗ

Документ.СчетФактураВыданный

ГДЕ

НЕ РЕГВЫР(Номер, "^[А-Я]{3}-\d{6}$")

Как ускорить поиск по большим текстовым полям?

Для полей с большим объемом текста (например, Комментарий в документах) создайте вычисляемое поле с хэшем или сокращенной версией текста, а поиск выполняйте по нему. Например:

ВЫБРАТЬ

ИД,

ЛЕВ(Комментарий, 100) КАК КороткийКомментарий

ИЗ

Документ.ЗаказПокупателя

ГДЕ

СОДЕРЖИТ(ЛЕВ(Комментарий, 100), "искомая подстрока")

Частые ошибки и как их избежать

Даже опытные разработчики иногда сталкиваются с неожиданными результатами при поиске подстрок. Вот наиболее распространенные ошибки:

  • 🔠 Игнорирование регистра: забывают добавить третий параметр Ложь в СОДЕРЖИТ, из-за чего поиск не находит строки с другим регистром.
  • 📏 Неправильные позиции: в ПОДСТРОКА начальная позиция указывается с 1, а не с 0 (как в некоторых языках программирования).
  • 🚫 Пустые результаты: при использовании ПОИСК не проверяют результат на 0, что приводит к ошибкам в ПОДСТРОКА.
  • 🐌 Производительность: применяют сложные регулярные выражения к большим текстовым полям без индексов.

Типичный пример ошибки с позициями:

// ОШИБКА: попытаемся извлечь 5 символов начиная с 0-й позиции

ПОДСТРОКА("АБВГД", 0, 5) // Вернет ошибку!

// ПРАВИЛЬНО:

ПОДСТРОКА("АБВГД", 1, 5) // Вернет "АБВГД"

⚠️ Внимание: При работе с многобайтовыми кодировками (например, UTF-8) функции ПОДСТРОКА и ПОИСК считают позиции по байтам, а не по символам. Для кириллических строк это может приводить к неожиданным результатам. В таких случаях переносите логику в программный код с использованием метода Строка.ПозицияПодстроки().

Еще одна распространенная проблема — поиск подстроки в NULL-значениях. Все функции поиска вернут ошибку, если строка содержит NULL. Всегда добавляйте проверку:

ГДЕ

Поле ЕСТЬ NULL ИЛИ СОДЕРЖИТ(Поле, "подстрока")

FAQ: Ответы на частые вопросы

Можно ли в запросе 1С использовать оператор LIKE?

Нет, в классических запросах 1С оператора LIKE нет. Вместо него используйте:

  • Функцию СОДЕРЖИТ для простого поиска
  • Оператор ПОДОБНО в версиях 8.3.15+ (аналог LIKE)
  • Регулярные выражения (РЕГВЫР) для сложных шаблонов
Как сделать поиск по нескольким подстрокам в одном запросе?

Есть три основных подхода:

  1. Использовать несколько условий с ИЛИ:
    ГДЕ СОДЕРЖИТ(Поле, "подстрока1")
    

    ИЛИ СОДЕРЖИТ(Поле, "подстрока2")

  2. Применить регулярное выражение:
    ГДЕ РЕГВЫР(Поле, "подстрока1|подстрока2")
  3. Перенести логику в программный код с параметром массива (оптимально для больших наборов подстрок).
Почему ПОИСК возвращает 0, хотя подстрока есть в строке?

Наиболее вероятные причины:

  • Регистр символов не совпадает (по умолчанию поиск регистрочувствительный)
  • В строке есть непечатаемые символы (пробелы, табуляции, переводы строк)
  • Используется многобайтовая кодировка, и функция считает позиции по байтам
  • Строка содержит NULL-значение

Проверьте строку с помощью СОКРЛП(Поле) (удалит пробелы) и ВРЕГ(Поле) (приведет к верхнему регистру).

Как извлечь все подстроки, соответствующие регулярному выражению?

В самом запросе это сделать невозможно — РЕГВЫР только проверяет соответствие шаблону. Для извлечения всех вхождений:

  1. Выполните запрос для отбора строк, содержащих искомый шаблон
  2. В программном коде обработайте каждую строку с помощью объекта РегулярноеВыражение:
    РегВыр = Новый РегулярноеВыражение("шаблон");
    

    Результаты = РегВыр.Найти(Строка);

    Пока Результаты.Следующий() Цикл

    Сообщить(Результаты.Значение);

    КонецЦикла;

Можно ли в запросе 1С использовать подстановочные знаки * и ? как в Windows?

Нет, в запросах 1С нет поддержки подстановочных знаков * и ? в стиле Windows. Альтернативы:

  • В версиях 8.3.15+ используйте ПОДОБНО с % и _ (как в SQL)
  • Для простых случаев комбинируйте ЛЕВ, ПРАВ и СРЕД с проверками длины
  • Для сложных шаблонов применяйте регулярные выражения