Поиск подстроки в строке — одна из самых частых задач при работе с данными в 1С:Предприятие.hether вы ищете клиента по фрагменту названия, фильтруете документы по части номера или анализируете текстовую информацию в отчетах, умение правильно составлять запросы с поиском подстрок сэкономит часы работы. В этой статье разберем все доступные способы: от стандартных функций языка запросов до нетривиальных приемов с регулярными выражениями.
Особенность поиска в 1С заключается в том, что здесь нет универсального оператора как 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")ИЛИ СОДЕРЖИТ(Поле, "подстрока2")
- Применить регулярное выражение:
ГДЕ РЕГВЫР(Поле, "подстрока1|подстрока2")- Перенести логику в программный код с параметром массива (оптимально для больших наборов подстрок).
Почему ПОИСК возвращает 0, хотя подстрока есть в строке?
Наиболее вероятные причины:
- Регистр символов не совпадает (по умолчанию поиск регистрочувствительный)
- В строке есть непечатаемые символы (пробелы, табуляции, переводы строк)
- Используется многобайтовая кодировка, и функция считает позиции по байтам
- Строка содержит
NULL-значениеПроверьте строку с помощью
СОКРЛП(Поле)(удалит пробелы) иВРЕГ(Поле)(приведет к верхнему регистру).Как извлечь все подстроки, соответствующие регулярному выражению?
В самом запросе это сделать невозможно —
РЕГВЫРтолько проверяет соответствие шаблону. Для извлечения всех вхождений:
- Выполните запрос для отбора строк, содержащих искомый шаблон
- В программном коде обработайте каждую строку с помощью объекта
РегулярноеВыражение:РегВыр = Новый РегулярноеВыражение("шаблон");Результаты = РегВыр.Найти(Строка);
Пока Результаты.Следующий() Цикл
Сообщить(Результаты.Значение);
КонецЦикла;
Можно ли в запросе 1С использовать подстановочные знаки * и ? как в Windows?
Нет, в запросах 1С нет поддержки подстановочных знаков
*и?в стиле Windows. Альтернативы:
- В версиях 8.3.15+ используйте
ПОДОБНОс%и_(как в SQL)- Для простых случаев комбинируйте
ЛЕВ,ПРАВиСРЕДс проверками длины- Для сложных шаблонов применяйте регулярные выражения