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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Особенности работы функций поиска строк в 1С

В платформе 1С поведение строковых операций разделено на два принципиально разных механизма:

  1. Прямое сравнение строк через оператор =. При стандартном сравнении строк (например, в выражении Если Строка1 = Строка2 Тогда) платформа игнорирует регистр символов. Выражение "ТЕКСТ" = "текст" вернет значение Истина.
  2. Поиск подстроки через функции Найти() и СтрНайти(). Встроенные функции поиска выполняют посимвольное бинарное сравнение кодов символов. По этой причине функции Найти() и более современная СтрНайти() всегда были и остаются строго чувствительными к регистру. Никаких встроенных параметров для отключения регистра в этих функциях не предусмотрено.

Таким образом, чувствительность к регистру в функциях поиска — это штатное поведение платформы всех версий (начиная с 7.7 и во всех релизах 8.x), а не ошибка конкретного релиза.

Основной способ: приведение строк к единому регистру через ВРег() или НРег()

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

Рассмотрим базовый пример:


ГдеИщем = "Номенклатура: Стол письменный";
ЧтоИщем = "стол";

// Поиск с приведением к верхнему регистру
Позиция = СтрНайти(ВРег(ГдеИщем), ВРег(ЧтоИщем));

Если Позиция > 0 Тогда
    // Подстрока найдена без учета регистра
КонецЕсли;

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

Оптимизация поиска в циклах и массивах данных

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

Разберем пример оптимизированного обхода таблицы:


ИскомыйОбразец = "комплект";
// Преобразуем образец один раз до начала цикла
ОбразецВРег = ВРег(ИскомыйОбразец);

Для Каждого Стр Из ТаблицаТоваров Цикл
    // Внутри цикла преобразуем только проверяемую строку
    Если СтрНайти(ВРег(Стр.Наименование), ОбразецВРег) > 0 Тогда
        Стр.Выбран = Истина;
    КонецЕсли;
КонецЦикла;

Нюанс с буквами «Е» и «Ё»

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


ТекстНорм = СтрЗаменить(ВРег(ГдеИщем), "Ё", "Е");
ОбразецНорм = СтрЗаменить(ВРег(ЧтоИщем), "Ё", "Е");

Позиция = СтрНайти(ТекстНорм, ОбразецНорм);

Альтернативные способы регистронезависимого поиска

В зависимости от архитектурных условий задачи можно использовать и другие инструменты платформы:

  1. Поиск в запросах через оператор ПОДОБНО. В базах данных под управлением MS SQL Server при стандартной настройке сопоставления (_CI_AS — Case Insensitive) поиск через ПОДОБНО "%образец%" по умолчанию не учитывает регистр. Однако для гарантированной кроссплатформенности (в файловых базах и PostgreSQL) рекомендуется также оборачивать поля в функции ВРЕГ() / НРЕГ() прямо в тексте запроса.
  2. Использование регулярных выражений (VBScript.RegExp). Для сложного сопоставления шаблонов в среде Windows можно создать COM-объект регулярных выражений и установить его свойство IgnoreCase = Истина.
  3. Полнотекстовый поиск платформы. Для глобального поиска по реквизитам информационной базы стандартный механизм полнотекстового поиска 1С автоматически игнорирует регистр букв и выполняет поиск с учетом словоформ.
← На главную