К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как в 1С получить часть строки

Как в 1С получить часть строки: функции Лев, Прав, Сред, СтрНайти, примеры кода, типичные ошибки с нумерацией символов и обработкой пробелов.

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

Ключевая особенность, о которой часто забывают разработчики, пришедшие из других языков: нумерация символов в строке в 1С начинается с единицы, а не с нуля. Функция Сред(Строка, 2, 3) вернёт символы со второго по четвёртый, а не с третьего по пятый. Большинство ошибок при извлечении части строки связано именно с этим смещением.

Ниже разобраны все четыре функции с синтаксисом и примерами, типовые сценарии вроде извлечения подстроки до и после разделителя, а также проверка граничных случаев — пустых строк, отсутствия искомого фрагмента и пробелов по краям.

Функции Лев, Прав и Сред: синтаксис и примеры

Три базовые функции отличаются только тем, откуда отсчитывается фрагмент. Лев(Строка, ЧислоСимволов) возвращает указанное количество символов с начала строки. Прав(Строка, ЧислоСимволов) — такое же количество с конца. Сред(Строка, НачальнаяПозиция, ЧислоСимволов) — фрагмент заданной длины, начиная с указанной позиции.

Строка = "АБВГ-00125";

ПервыеТри = Лев(Строка, 3); // "АБВ"

ПоследниеТри = Прав(Строка, 3); // "125"

Фрагмент = Сред(Строка, 5, 5); // "00125"

Если запрошенное количество символов больше длины строки, ошибки не произойдёт — функция просто вернёт всю строку или доступный остаток. Например, Лев("АБ", 10) вернёт «АБ». Это удобно для защитного кода, но одновременно маскирует ошибки логики: если вы ожидали ровно 8 символов, а пришло 3, стоит проверять длину через СтрДлина до извлечения.

У функции Сред третий параметр можно опустить — тогда возвращаются все символы от начальной позиции до конца строки. Конструкция Сред(Строка, 5) эквивалентна «отрезать первые четыре символа», и это самый короткий способ удаления префикса известной длины.

СтрНайти: поиск позиции подстроки

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

Строка = "Заказ № АБ-12345 от клиента";

Позиция = СтрНайти(Строка, "№"); // 7

Номер = Сред(Строка, Позиция + 2); // "АБ-12345 от клиента"

Функция имеет необязательные параметры: направление поиска (с начала или с конца) и номер вхождения. Направление «с конца» полезно, когда разделитель встречается несколько раз и нужен последний — классический пример, точка в имени файла перед расширением. Поиск выполняется с учётом регистра: «Аб» и «АБ» для СтрНайти — разные подстроки.

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

bsl
ИмяФайла = "отчет.итоговый.xlsx";
ПозицияТочки = СтрНайти(ИмяФайла, ".", НаправлениеПоиска.СКонца);
Если ПозицияТочки > 0 Тогда
    Расширение = Сред(ИмяФайла, ПозицияТочки + 1); // "xlsx"
КонецЕсли;

Извлечение части строки до и после разделителя

Самая частая практическая задача — взять фрагмент до разделителя или после него. Оба варианта строятся на связке СтрНайти плюс Лев или Сред. Для фрагмента до разделителя: Лев(Строка, Позиция - 1). Для фрагмента после: Сред(Строка, Позиция + СтрДлина(Разделитель)).

Строка = "Иванов И.И.:менеджер";

Поз = СтрНайти(Строка, ":");

Если Поз > 0 Тогда

ФИО = Лев(Строка, Поз - 1); // "Иванов И.И."

Должность = Сред(Строка, Поз + 1); // "менеджер"

Иначе

// разделителя нет — строка целиком относится к первой части

ФИО = Строка;

Должность = "";

КонецЕсли;

Обратите внимание на смещение: позиция указывает на сам разделитель, поэтому для левой части берём на один символ меньше, а для правой начинаем на длину разделителя дальше. Если разделитель состоит из нескольких символов (например, « - » с пробелами), смещение вычисляется через СтрДлина(Разделитель), а не жёстко заданной единицей.

Порядок действий
  1. 1
    Найдите позицию разделителя через СтрНайти
  2. 2
    Проверьте, что позиция больше нуля — разделитель существует
  3. 3
    Извлеките левую часть: Лев(Строка, Позиция - 1)
  4. 4
    Извлеките правую часть: Сред(Строка, Позиция + СтрДлина(Разделитель))
  5. 5
    Уберите краевые пробелы через СокрЛП при необходимости

Разбор строки с несколькими разделителями через СтрРазделить

Когда в строке несколько одинаковых разделителей — CSV-подобные данные, перечни через запятую, полный путь через «\» — вручную искать каждое вхождение неудобно. Функция СтрРазделить(Строка, Разделитель) возвращает массив частей, из которого элементы берутся по индексу. Индексы массива, в отличие от позиций в строке, начинаются с нуля.

Строка = "001;Кабель ВВГ 3х2.5;м;150";

Части = СтрРазделить(Строка, ";");

Артикул = Части[0]; // "001"

Наименование = Части[1]; // "Кабель ВВГ 3х2.5"

Единица = Части[2]; // "м"

Количество = Число(Части[3]); // 150

Перед обращением к элементу по индексу проверяйте размер массива: если в исходной строке оказалось меньше разделителей, чем ожидалось, обращение к несуществующему индексу вызовет ошибку выполнения. Безопасный шаблон — сравнить Части.Количество() с требуемым числом полей.

Обратная задача — склеить массив строк в одну через разделитель — решается функцией СтрСоединить(Массив, Разделитель). Пара «СтрРазделить / СтрСоединить» покрывает большинство сценариев обмена данными в текстовых форматах без ручного посимвольного разбора.

Обработка пробелов и невидимых символов

Реальные данные из файлов, штрихкодов и пользовательского ввода почти всегда содержат лишние пробелы по краям. После извлечения фрагмента применяйте СокрЛП (убирает пробелы слева и справа) или СокрЛ / СокрП по отдельности. Без этого сравнение извлечённого значения с эталоном может неожиданно не сработать: «АБ-123» и «АБ-123 » — разные строки.

Отдельная ловушка — неразрывные пробелы и символы табуляции, которые СокрЛП в ряде случаев обрабатывает, но визуально в отладчике они неотличимы от обычных пробелов. Если строка «не чистится», проверьте коды символов через КодСимвола и при необходимости замените проблемные символы через СтрЗаменить до извлечения фрагмента.

Типичные ошибки
01
Считать позиции с нуля — смещение всех фрагментов на один символ
02
Не проверять результат СтрНайти на ноль — при отсутствии разделителя Лев(Строка, -1) вернёт пустую строку и логика молча сломается
03
Забыть учесть длину многосимвольного разделителя при вычислении правой части
04
Сравнивать извлечённый фрагмент без СокрЛП — сравнение не проходит из-за краевых пробелов
05
Обращаться к элементу массива после СтрРазделить без проверки его размера

Проверка результата и граничные случаи

Надёжный код извлечения подстроки всегда отвечает на три вопроса: что будет, если строка пустая; что будет, если разделитель не найден; что будет, если искомый фрагмент оказался короче ожидаемого. Пустая строка — штатная ситуация для необязательных реквизитов, и Лев("", 5) вернёт пустую строку без ошибки, но последующая логика (например, поиск по справочнику) должна это учитывать.

Для отладки используйте СтрДлина и вывод промежуточных значений через Сообщить или точку останова в конфигураторе. Быстрый способ убедиться, что позиция найдена верно: вывести Сред(Строка, Позиция, 1) — должен вернуться сам разделитель.

Контрольные точки

Как проверить результат

Позиция разделителя
Норма

СтрНайти вернула число больше нуля

Тревожный признак

Вернулся 0 — разделителя нет, извлекать фрагмент нельзя

Длина извлечённого фрагмента
Норма

Совпадает с ожидаемой длиной значения

Тревожный признак

Фрагмент короче или пустой — проверьте смещение и исходные данные

Символ в найденной позиции
Норма

Сред(Строка, Позиция, 1) равен разделителю

Тревожный признак

Вернулся другой символ — позиция рассчитана неверно

Сравнение с эталоном
Норма

Совпадает после СокрЛП

Тревожный признак

Не совпадает — ищите скрытые пробелы или различия регистра

FAQ: частые вопросы о работе с подстроками в 1С

Как получить первый символ строки?

Используйте Лев(Строка, 1) или Сред(Строка, 1, 1) — оба варианта вернут первый символ. Для пустой строки результатом будет пустая строка, ошибки не возникнет.

Как удалить первые N символов из строки?

Примените Сред(Строка, N + 1) без третьего параметра — вернутся все символы начиная с позиции N+1, то есть строка без первых N символов. Если строка короче N, результат будет пустым.

Что вернёт СтрНайти, если подстрока не найдена?

Ноль. Это не ошибка выполнения, а нормальное возвращаемое значение, поэтому перед использованием позиции в Лев или Сред всегда проверяйте условие Позиция > 0.

Как извлечь текст между двумя разделителями?

Найдите позицию первого разделителя, от него — позицию второго через СтрНайти с параметром начальной позиции поиска, затем возьмите Сред(Строка, Позиция1 + ДлинаРазделителя, Позиция2 - Позиция1 - ДлинаРазделителя). Для строк с повторяющимися разделителями проще использовать СтрРазделить и взять нужный элемент массива.

Учитывается ли регистр при поиске подстроки?

Да, СтрНайти различает регистр. Если регистр не гарантирован, приведите копию строки и искомую подстроку к одному регистру через НРег или ВРег, найдите позицию в копии, а фрагмент извлекайте из исходной строки — позиции совпадут.

Как получить последние символы строки неизвестной длины?

Функция Прав(Строка, N) сама работает от конца строки, знать полную длину не требуется. Если запрошенное N больше длины строки, вернётся вся строка целиком без ошибки.

Итог

Что важно запомнить

Часть строки в 1С извлекают функции Лев, Прав и Сред, позицию разделителя даёт СтрНайти, а строки с несколькими разделителями разбирает СтрРазделить. Позиции считаются с 1, нулевой результат СтрНайти проверяется всегда, а извлечённый фрагмент перед сравнением очищается через СокрЛП.