Как найти точное совпадение значения в строке: решаем проблему частичного вхождения СтрНайти

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

В процессе разработки на платформе 1С:Предприятие 8 программисты часто сталкиваются с необходимостью поиска определенных данных внутри текстовых строк. Одной из самых распространенных функций для этого является СтрНайти. Однако стандартное поведение этой функции может преподнести сюрприз: она ищет подстроку, а не целое слово. Это приводит к ситуациям, когда при поиске короткого кода (например, «130») система находит его внутри более длинного кода («1306»), что является логической ошибкой во многих бизнес-задачах.

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

Выясним причину: почему СтрНайти работает именно так

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

Рассмотрим пример, который иллюстрирует проблему:


ИсходнаяСтрока = "Артикул 1306 на складе";
ИскомоеЗначение = "130";
Позиция = СтрНайти(ИсходнаяСтрока, ИскомоеЗначение);
// Позиция будет равна 9, хотя мы искали именно "130", а не часть "1306"

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

Метод 1: Использование СтрРазделить и поиск по массиву

Если искомые значения в строке разделены пробелами, запятыми или другими знаками препинания, самым правильным подходом будет разбиение строки в массив. Рассмотрим этот алгоритм по шагам:

  1. Определяем символы-разделители (например, пробел).
  2. Превращаем строку в массив слов с помощью функции СтрРазделить.
  3. Обходим массив в цикле и сравниваем каждое слово с искомым значением оператором =.

Пример реализации:


Текст = "прав 1306 бючсп";
МассивСлов = СтрРазделить(Текст, " ", Ложь); // Разбиваем по пробелу
НайденоТочно = Ложь;

Для Каждого Слово Из МассивСлов Цикл
    Если Слово = "130" Тогда
        НайденоТочно = Истина;
        Прервать;
    КонецЕсли;
КонецЦикла;

Этот способ является наиболее надежным, так как оператор сравнения = проверяет полное идентичное совпадение строк.

Метод 2: Прием «обрамления разделителями»

Бывают ситуации, когда разбивать строку в массив слишком затратно по ресурсам или неудобно. В этом случае программисты 1С часто используют элегантный «хак». Мы искусственно добавляем разделители (пробелы) в начало и конец как исходной строки, так и искомого значения. Разберем, как это работает.

Если мы будем искать " 130 " (с пробелами) в строке " 1306 ", поиск вернет 0, так как после «0» идет «6», а не пробел. А в строке " 130 " поиск завершится успехом.


ИсходнаяСтрока = "Код 1306 и код 130";
Искомое = "130";
// Добавляем пробелы для поиска точного вхождения
Если СтрНайти(" " + ИсходнаяСтрока + " ", " " + Искомое + " ") > 0 Тогда
    Сообщить("Найдено точное совпадение!");
КонецЕсли;

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

Метод 3: Использование регулярных выражений (RegExp)

Для максимально точного поиска, учитывающего границы слов (пробелы, начало строки, знаки препинания), лучше всего подходят регулярные выражения. В языке 1С нет встроенного объекта RegExp, но мы можем воспользоваться COM-объектом VBScript.RegExp.

Проанализируем код:


RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина; // Игнорировать регистр
RegExp.Global = Ложь;       // Искать только первое вхождение
// Шаблон \b означает границу слова
RegExp.Pattern = "\b" + "130" + "\b";

ТекстДляПоиска = "склад 1306, ячейка 130";
Если RegExp.Test(ТекстДляПоиска) Тогда
    Сообщить("Число 130 найдено как отдельное слово!");
КонецЕсли;

Символ \b в шаблоне гарантирует, что перед и после искомой подстроки нет других букв или цифр. Это самый «профессиональный» способ решения задачи.

Метод 4: Поиск в запросах с помощью ПОДОБНО

Если задача стоит найти данные не в текстовой переменной, а в базе данных (например, найти все документы, где в комментарии указан код 130), то используется язык запросов. Здесь также возникает проблема частичного вхождения при использовании %.

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


ВЫБРАТЬ
    Ссылка
ИЗ
    Справочник.Номенклатура
ГДЕ
    Наименование ПОДОБНО "130 %"  // В начале строки
    ИЛИ Наименование ПОДОБНО "% 130"  // В конце строки
    ИЛИ Наименование ПОДОБНО "% 130 %" // В середине строки
    ИЛИ Наименование = "130"           // Полное совпадение

Оптимизация производительности

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

Резюме

Функция СтрНайти — это мощный, но «простой» инструмент. Для поиска точных совпадений (целых слов) всегда используйте дополнительные проверки:

  1. Либо разбивайте строку на части через СтрРазделить.
  2. Либо используйте регулярные выражения для контроля границ слова.
  3. Либо применяйте метод обрамления пробелами для простых случаев.

Выбор метода зависит от сложности структуры вашего текста и требований к производительности. Надеемся, эти шаги помогут вам избежать ошибок при обработке строковых данных в 1С!

← На главную