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

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

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

Способ 1. Замена по номеру вхождения подстроки

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

Рассмотрим алгоритм действий:

  1. Определяем позицию начала нужного нам вхождения.
  2. Разрезаем исходную строку на две части: до и после искомого слова.
  3. Собираем новую строку, вставив между частями новое слово.

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


// Исходные данные
ИсходныйТекст = "Фото тут. Фото тут. Фото тут.";
ИскомоеСлово = "тут";
НовоеСлово = "здесь";
НомерНужногоВхождения = 2;

// Находим позицию 2-го вхождения слова "тут"
Позиция = СтрНайти(ИсходныйТекст, ИскомоеСлово, НаправлениеПоиска.СНачала, , НомерНужногоВхождения);

Если Позиция > 0 Тогда
    // Вычисляем длину слова, чтобы знать, сколько символов "вырезать"
    ДлинаСтарого = СтрДлина(ИскомоеСлово);
    
    // Собираем результат
    ТекстДо = Лев(ИсходныйТекст, Позиция - 1);
    ТекстПосле = Сред(ИсходныйТекст, Позиция + ДлинаСтарого);
    
    Результат = ТекстДо + НовоеСлово + ТекстПосле;
    Сообщить(Результат); // Результат: "Фото тут. Фото здесь. Фото тут."
КонецЕсли;

Способ 2. Работа с интерактивно выделенным текстом на форме

Если ваша задача состоит в том, чтобы заменить слово, которое пользователь физически выделил курсором в поле ввода, нам не нужно ничего искать. Платформа 1С предоставляет доступ к метаданным выделения через свойства элементов формы.

Для обычного текстового поля (строкового реквизита) на управляемой форме мы можем использовать следующие свойства:

Разберем, как это работает на практике. Допустим, у нас есть поле ТекстПисьма на форме:


// Процедура вызывается по нажатию кнопки "Заменить выделенное"
&НаКлиенте
Процедура ЗаменитьВыделенное(Команда)
    
    ЭлементТекст = ЭтаФорма.Элементы.ТекстПисьма;
    
    // Получаем текущие границы выделения
    Старт = ЭлементТекст.НачалоВыделения;
    Длина = ЭлементТекст.ДлинаВыделения;
    
    Если Длина > 0 Тогда
        ПолныйТекст = Объект.ТекстПисьма;
        НовоеСлово = "Замена";
        
        // Формируем новую строку на основе позиций
        ТекстДо = Лев(ПолныйТекст, Старт - 1);
        ТекстПосле = Сред(ПолныйТекст, Старт + Длина);
        
        Объект.ТекстПисьма = ТекстДо + НовоеСлово + ТекстПосле;
    КонецЕсли;
    
КонецПроцедуры

Способ 3. Использование регулярных выражений (RegExp)

Для более сложных случаев, когда нужно учитывать границы слов (чтобы не заменить «тут» внутри слова «институт»), идеально подходят регулярные выражения. В современных версиях платформы (8.3.24+) появилась встроенная поддержка объекта РегулярноеВыражение. Для более старых версий мы используем COM-объект VBScript.RegExp.

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


// Пример для новых версий 1С
РегЭксп = Новый РегулярноеВыражение("\b" + ИскомоеСлово + "\b");
// Метод Заменить может заменить все, но RegExp позволяет 
// строить более гибкие условия поиска (например, только слово целиком)
Результат = РегЭксп.Заменить(ИсходныйТекст, НовоеСлово);

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

Способ 4. Метод временных маркеров

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

Алгоритм действий следующий:

  1. Находим позицию нужного вхождения.
  2. Вместо замены на финальное слово, вставляем уникальный GUID или строку вида {#МАРКЕР_1#}.
  3. После проведения всех манипуляций в тексте, делаем финальный проход СтрЗаменить, заменяя маркер на целевое значение.

Особенности работы с Форматированным документом

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

Рассмотрим шаги для безопасной замены:

  1. Используем объект ОписаниеВыделения.
  2. Применяем метод ЗаменитьТекст() к объекту текстового документа, указывая полученные границы. Это позволит вставить текст, сохранив окружающее оформление.

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

← На главную