При обработке текстовых данных, сетевых адресов или путей к файлам часто возникает типовая задача: найти последний символ-разделитель (например, точку) и отсечь либо заменить все символы, идущие после него. Классический пример — изменение последнего октета в IP-адресе вида 192.168.43.12 на значение 1, чтобы получить 192.168.43.1.
В зависимости от версии используемой платформы 1С:Предприятие для решения этой задачи применяются разные подходы. Разберем подробно современные и классические методы реализации.
В современных релизах платформы появились мощные функции для манипуляции строками: СтрНайти, СтрРазделить и СтрСоединить. Рассмотрим два удобных способа их применения.
Способ А. Поиск точки с конца строки через СтрНайти:
Функция СтрНайти поддерживает параметр направления поиска, что позволяет найти позицию последнего вхождения символа в одну строку кода.
ИсходныйIP = "192.168.43.12";
ПозицияТочки = СтрНайти(ИсходныйIP, ".", НаправлениеПоиска.СКонца);
Если ПозицияТочки > 0 Тогда
Результат = Лев(ИсходныйIP, ПозицияТочки) + "1";
Иначе
Результат = ИсходныйIP;
КонецЕсли;
Способ Б. Разбиение строки на массив через СтрРазделить:
Если требуется гарантированно изменить четвертый октет адреса, разобьем строку на массив, заменим нужный элемент и соберем строку обратно.
ИсходныйIP = "192.168.43.12";
МассивОктетов = СтрРазделить(ИсходныйIP, ".");
Если МассивОктетов.Количество() = 4 Тогда
МассивОктетов[3] = "1";
Результат = СтрСоединить(МассивОктетов, ".");
КонецЕсли;
На устаревших платформах встроенная функция Найти ищет подстроку исключительно слева направо и не принимает направление поиска. Чтобы быстро найти последнюю точку, организуем цикл от конца строки к ее началу с помощью функции Сред.
ИсходныйIP = "192.168.43.12";
ДлинаСтроки = СтрДлина(ИсходныйIP);
Результат = ИсходныйIP;
Пока ДлинаСтроки > 0 Цикл
Если Сред(ИсходныйIP, ДлинаСтроки, 1) = "." Тогда
Результат = Лев(ИсходныйIP, ДлинаСтроки) + "1";
Прервать;
КонецЕсли;
ДлинаСтроки = ДлинаСтроки - 1;
КонецЦикла;
Этот алгоритм работает максимально быстро, так как прерывает обход сразу после обнаружения первой справа точки и не выполняет лишних операций конкатенации.
Оформим логику поиска позиции последнего символа в виде отдельной вспомогательной функции, которую можно вынести в общий модуль конфигурации.
// Осуществляет поиск символа, начиная с конца строки.
// Возвращает позицию символа в строке либо 0, если символ не найден.
Функция НайтиСимволСКонца(Знач Строка, Знач Символ) Экспорт
ДлинаСимвола = СтрДлина(Символ);
Для Позиция = -СтрДлина(Строка) По -1 Цикл
Если Сред(Строка, -Позиция, ДлинаСимвола) = Символ Тогда
Возврат -Позиция;
КонецЕсли;
КонецЦикла;
Возврат 0;
КонецФункции
// Пример использования:
Поз = НайтиСимволСКонца("192.168.43.12", ".");
Если Поз > 0 Тогда
Результат = Лев("192.168.43.12", Поз) + "1";
КонецЕсли;
Если мы не хотим перебирать строку посимвольно, можно последовательно находить все точки слева направо, смещая указатель позиции до тех пор, пока вхождения не закончатся.
ИсходныйIP = "192.168.43.12";
ПозицияПоследнейТочки = 0;
Смещение = 0;
ОстатокСтроки = ИсходныйIP;
Пока Истина Цикл
Поз = Найти(ОстатокСтроки, ".");
Если Поз = 0 Тогда
Прервать;
КонецЕсли;
ПозицияПоследнейТочки = Смещение + Поз;
Смещение = ПозицияПоследнейТочки;
ОстатокСтроки = Сред(ОстатокСтроки, Поз + 1);
КонецЦикла;
Если ПозицияПоследнейТочки > 0 Тогда
Результат = Лев(ИсходныйIP, ПозицияПоследнейТочки) + "1";
КонецЕсли;
Для конфигураций на платформах 7.7, 8.0, 8.1 и 8.2 под управлением ОС Windows можно воспользоваться COM-объектом регулярных выражений. Это позволяет решить задачу без циклов.
РегЭксп = Новый COMОбъект("VBScript.RegExp");
РегЭксп.Pattern = "\.[^.]*$";
РегЭксп.Global = Ложь;
ИсходныйIP = "192.168.43.12";
Результат = РегЭксп.Replace(ИсходныйIP, ".1");
При обработке строк обратите внимание на следующие особенности:
Символы.ПС: Распространенный в старых версиях прием с заменой точки на перевод строки (СтрЗаменить(Стр, ".", Символы.ПС)) и последующим вызовом СтрПолучитьСтроку может давать сбои, если в исходном тексте уже присутствуют служебные невидимые символы переноса строк.VBScript.RegExp работает только в среде Windows. Если сервер 1С работает под управлением Linux, следует использовать алгоритмы на чистом встроенном языке 1С.0, чтобы избежать ошибок отсечения всей строки при передаче некорректного адреса.