Как в 1С обрезать строку с определенной позиции до первого вхождения символа-разделителя

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

В практике разработчика 1С часто возникают задачи по парсингу текстовых строк, полученных из внешних систем, файлов или сформированных внутри программы. Одной из типовых задач является извлечение фрагмента строки, который начинается с фиксированной позиции, но имеет переменную длину, ограниченную определенным символом (например, %, ; или *). В этой статье мы подробно разберем, как правильно реализовать такой алгоритм, проанализируем различные подходы и выберем наиболее оптимальный и безопасный код.

Постановка задачи и анализ входных данных

Представим ситуацию: у нас есть строка вида %3%2%777643%нужный_кусок%3434. Нам необходимо извлечь текст нужный_кусок. Мы точно знаем, что этот текст всегда начинается с 13-го символа, но его длина может меняться. Конечным ограничителем служит символ процента (%). Наша цель — получить этот фрагмент, не включая сам разделитель.

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

Решение 1: Классический метод с использованием Сред() и Найти()

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


ИсходнаяСтрока = "%3%2%777643%нужный_кусок%3434";
НачальнаяПозиция = 13;
// Отрезаем всё, что идет до нужного куска
ОстатокСтроки = Сред(ИсходнаяСтрока, НачальнаяПозиция);
// Ищем позицию разделителя в остатке
ПозицияРазделителя = Найти(ОстатокСтроки, "%");

Если ПозицияРазделителя > 0 Тогда
    Результат = Лев(ОстатокСтроки, ПозицияРазделителя - 1);
Иначе
    // Если разделитель не найден, берем строку до конца
    Результат = ОстатокСтроки;
КонецЕсли;

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

Решение 2: Компактная запись (в одну строку)

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

Результат = Сред(стр, 13, Найти(Сред(стр, 13), "%") - 1);

В данном случае функция Сред() принимает три параметра: исходную строку, номер первого символа (13) и количество символов, которые нужно извлечь. Это количество мы вычисляем динамически: берем остаток строки, ищем в нем процент и вычитаем 1. Это решение достаточно эффективно, однако оно может вызвать ошибку времени выполнения, если символ % не будет найден (функция вернет 0, и вычитание даст -1, что недопустимо для параметра длины в Сред()).

Решение 3: Использование функции СтрНайти (для платформы 8.3.6 и выше)

Современные версии платформы 1С предоставляют более удобный инструмент — функцию СтрНайти(). Она позволяет искать символ, начиная с определенной позиции, что избавляет нас от необходимости предварительно обрезать строку с помощью Сред(). Это повышает производительность и читаемость кода.

Рассмотрим, как это реализовать:


ИсходнаяСтрока = "%3%2%777643%нужный_кусок%3434";
Начало = 13;
// Ищем символ "%" начиная с 13-й позиции
ПозицияПроцента = СтрНайти(ИсходнаяСтрока, "%", НаправлениеПоиска.С начала, Начало);

Если ПозицияПроцента > 0 Тогда
    ДлинаКуска = ПозицияПроцента - Начало;
    Результат = Сред(ИсходнаяСтрока, Начало, ДлинаКуска);
Иначе
    Результат = Сред(ИсходнаяСтрока, Начало);
КонецЕсли;

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

Решение 4: Разложение в массив через СтрРазделить

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


ИсходнаяСтрока = "%3%2%777643%нужный_кусок%3434";
МассивЧастей = СтрРазделить(ИсходнаяСтрока, "%", Ложь);

// Согласно примеру, нужный кусок — это 4-й элемент (если считать от 0)
// Но так как строка начинается с %, первый элемент массива будет пустым
Если МассивЧастей.Количество() > 4 Тогда
    Результат = МассивЧастей[4];
КонецЕсли;

Данный метод наиболее универсален, если вам нужно извлекать не один, а сразу несколько параметров из строки. Однако, если важна именно строгая позиция символа (например, 13-й байт), лучше придерживаться методов с Сред().

Рекомендации по безопасности кода

При работе со строками важно учитывать возможные исключительные ситуации. Разберем основные правила:

  1. Проверка на наличие разделителя: Всегда проверяйте результат функции Найти() или СтрНайти() на значение больше 0. Попытка передать отрицательную длину в функцию Сред() приведет к аварийному завершению работы кода.
  2. Проверка длины строки: Перед использованием Сред(Строка, 13) убедитесь, что сама ИсходнаяСтрока имеет длину не меньше 13 символов. Для этого используйте функцию СтрДлина().
  3. Обработка пустых строк: Если входная строка пуста, функции поиска вернут 0. Убедитесь, что логика вашей программы корректно обрабатывает такие случаи.
  4. Производительность: Если обработка строк происходит в цикле по тысячам записей, старайтесь избегать лишнего копирования строк. Функция СтрНайти() с указанием начальной позиции работает быстрее, чем комбинация Сред() и Найти(), так как не создает промежуточную подстроку в памяти.

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

← На главную