В практике разработчика 1С часто возникают задачи по парсингу текстовых строк, полученных из внешних систем, файлов или сформированных внутри программы. Одной из типовых задач является извлечение фрагмента строки, который начинается с фиксированной позиции, но имеет переменную длину, ограниченную определенным символом (например, %, ; или *). В этой статье мы подробно разберем, как правильно реализовать такой алгоритм, проанализируем различные подходы и выберем наиболее оптимальный и безопасный код.
Представим ситуацию: у нас есть строка вида %3%2%777643%нужный_кусок%3434. Нам необходимо извлечь текст нужный_кусок. Мы точно знаем, что этот текст всегда начинается с 13-го символа, но его длина может меняться. Конечным ограничителем служит символ процента (%). Наша цель — получить этот фрагмент, не включая сам разделитель.
Для решения этой задачи в языке 1С существуют базовые функции работы со строками: Сред(), Найти(), Лев() и более современная СтрНайти(). Рассмотрим по шагам, как построить надежный алгоритм.
Разберем самый популярный подход, который обсуждался на форуме. Суть его заключается в том, чтобы сначала отсечь начало строки до нужной нам позиции, а затем найти в остатке первый символ-разделитель. Посмотрим на пример кода:
ИсходнаяСтрока = "%3%2%777643%нужный_кусок%3434";
НачальнаяПозиция = 13;
// Отрезаем всё, что идет до нужного куска
ОстатокСтроки = Сред(ИсходнаяСтрока, НачальнаяПозиция);
// Ищем позицию разделителя в остатке
ПозицияРазделителя = Найти(ОстатокСтроки, "%");
Если ПозицияРазделителя > 0 Тогда
Результат = Лев(ОстатокСтроки, ПозицияРазделителя - 1);
Иначе
// Если разделитель не найден, берем строку до конца
Результат = ОстатокСтроки;
КонецЕсли;
Проанализируем, почему мы используем ПозицияРазделителя - 1. Функция Найти() возвращает позицию самого символа %. Поскольку нам нужен текст до него, мы вычитаем единицу, чтобы исключить сам разделитель из результата.
Иногда разработчики стремятся сократить код до одной строки. Рассмотрим вариант, который часто встречается в конфигурациях, но требует внимательности при расчете индексов. Проанализируем следующую конструкцию:
Результат = Сред(стр, 13, Найти(Сред(стр, 13), "%") - 1);
В данном случае функция Сред() принимает три параметра: исходную строку, номер первого символа (13) и количество символов, которые нужно извлечь. Это количество мы вычисляем динамически: берем остаток строки, ищем в нем процент и вычитаем 1. Это решение достаточно эффективно, однако оно может вызвать ошибку времени выполнения, если символ % не будет найден (функция вернет 0, и вычитание даст -1, что недопустимо для параметра длины в Сред()).
Современные версии платформы 1С предоставляют более удобный инструмент — функцию СтрНайти(). Она позволяет искать символ, начиная с определенной позиции, что избавляет нас от необходимости предварительно обрезать строку с помощью Сред(). Это повышает производительность и читаемость кода.
Рассмотрим, как это реализовать:
ИсходнаяСтрока = "%3%2%777643%нужный_кусок%3434";
Начало = 13;
// Ищем символ "%" начиная с 13-й позиции
ПозицияПроцента = СтрНайти(ИсходнаяСтрока, "%", НаправлениеПоиска.С начала, Начало);
Если ПозицияПроцента > 0 Тогда
ДлинаКуска = ПозицияПроцента - Начало;
Результат = Сред(ИсходнаяСтрока, Начало, ДлинаКуска);
Иначе
Результат = Сред(ИсходнаяСтрока, Начало);
КонецЕсли;
В этом примере мы сразу находим абсолютную позицию символа в строке. Вычитая из нее начальную позицию, мы получаем точную длину искомого фрагмента. Важный нюанс: если ПозицияПроцента равна 13 (разделитель стоит сразу в начале поиска), ДлинаКуска станет равной 0, и мы получим пустую строку, что логически верно.
Если ваша строка содержит много однотипных разделителей, и вы знаете порядковый номер нужного фрагмента, стоит рассмотреть функцию СтрРазделить(). Это особенно полезно, когда структура строки может незначительно меняться в начале, но количество разделителей остается постоянным.
ИсходнаяСтрока = "%3%2%777643%нужный_кусок%3434";
МассивЧастей = СтрРазделить(ИсходнаяСтрока, "%", Ложь);
// Согласно примеру, нужный кусок — это 4-й элемент (если считать от 0)
// Но так как строка начинается с %, первый элемент массива будет пустым
Если МассивЧастей.Количество() > 4 Тогда
Результат = МассивЧастей[4];
КонецЕсли;
Данный метод наиболее универсален, если вам нужно извлекать не один, а сразу несколько параметров из строки. Однако, если важна именно строгая позиция символа (например, 13-й байт), лучше придерживаться методов с Сред().
При работе со строками важно учитывать возможные исключительные ситуации. Разберем основные правила:
Найти() или СтрНайти() на значение больше 0. Попытка передать отрицательную длину в функцию Сред() приведет к аварийному завершению работы кода.Сред(Строка, 13) убедитесь, что сама ИсходнаяСтрока имеет длину не меньше 13 символов. Для этого используйте функцию СтрДлина().СтрНайти() с указанием начальной позиции работает быстрее, чем комбинация Сред() и Найти(), так как не создает промежуточную подстроку в памяти.Подводя итог, можно сказать, что для простых задач в старых конфигурациях отлично подходит метод из сообщения (23) форума, а для новых проектов на платформе 8.3.6+ рекомендуется использовать СтрНайти(). Это обеспечит вашему коду надежность и высокую скорость работы.