Разработка и Конфигурация · 9 мин
Как в 1С получить часть строки
Как в 1С получить часть строки: функции Лев, Прав, Сред, СтрНайти, примеры кода, типичные ошибки с нумерацией символов и обработкой пробелов.
Во встроенном языке 1С нет единой функции «подстрока» в привычном смысле — вместо неё используется набор из четырёх функций: Лев, Прав, Сред и СтрНайти. Их комбинации закрывают практически все задачи: извлечь первые символы кода, отрезать номер документа от префикса, вытащить значение между разделителями или получить расширение файла из полного имени.
Ключевая особенность, о которой часто забывают разработчики, пришедшие из других языков: нумерация символов в строке в 1С начинается с единицы, а не с нуля. Функция Сред(Строка, 2, 3) вернёт символы со второго по четвёртый, а не с третьего по пятый. Большинство ошибок при извлечении части строки связано именно с этим смещением.
Ниже разобраны все четыре функции с синтаксисом и примерами, типовые сценарии вроде извлечения подстроки до и после разделителя, а также проверка граничных случаев — пустых строк, отсутствия искомого фрагмента и пробелов по краям.
Функции Лев, Прав и Сред: синтаксис и примеры
Три базовые функции отличаются только тем, откуда отсчитывается фрагмент. Лев(Строка, ЧислоСимволов) возвращает указанное количество символов с начала строки. Прав(Строка, ЧислоСимволов) — такое же количество с конца. Сред(Строка, НачальнаяПозиция, ЧислоСимволов) — фрагмент заданной длины, начиная с указанной позиции.
Строка = "АБВГ-00125";
ПервыеТри = Лев(Строка, 3); // "АБВ"
ПоследниеТри = Прав(Строка, 3); // "125"
Фрагмент = Сред(Строка, 5, 5); // "00125"
Если запрошенное количество символов больше длины строки, ошибки не произойдёт — функция просто вернёт всю строку или доступный остаток. Например, Лев("АБ", 10) вернёт «АБ». Это удобно для защитного кода, но одновременно маскирует ошибки логики: если вы ожидали ровно 8 символов, а пришло 3, стоит проверять длину через СтрДлина до извлечения.
У функции Сред третий параметр можно опустить — тогда возвращаются все символы от начальной позиции до конца строки. Конструкция Сред(Строка, 5) эквивалентна «отрезать первые четыре символа», и это самый короткий способ удаления префикса известной длины.
СтрНайти: поиск позиции подстроки
Когда длина префикса заранее неизвестна, сначала определяют позицию разделителя функцией СтрНайти(Строка, ПодстрокаПоиска). Она возвращает номер первого символа найденного вхождения или 0, если подстрока не найдена. Ноль — штатный результат, а не ошибка, и его обязательно нужно обрабатывать.
Строка = "Заказ № АБ-12345 от клиента";
Позиция = СтрНайти(Строка, "№"); // 7
Номер = Сред(Строка, Позиция + 2); // "АБ-12345 от клиента"
Функция имеет необязательные параметры: направление поиска (с начала или с конца) и номер вхождения. Направление «с конца» полезно, когда разделитель встречается несколько раз и нужен последний — классический пример, точка в имени файла перед расширением. Поиск выполняется с учётом регистра: «Аб» и «АБ» для СтрНайти — разные подстроки.
Если регистр заранее неизвестен, приведите обе строки к одному регистру через НРег или ВРег перед поиском. Но помните: позицию вы получите для преобразованной строки, а извлекать фрагмент нужно из исходной — позиции совпадут, так как длина при смене регистра не меняется.
ИмяФайла = "отчет.итоговый.xlsx";
ПозицияТочки = СтрНайти(ИмяФайла, ".", НаправлениеПоиска.СКонца);
Если ПозицияТочки > 0 Тогда
Расширение = Сред(ИмяФайла, ПозицияТочки + 1); // "xlsx"
КонецЕсли;Извлечение части строки до и после разделителя
Самая частая практическая задача — взять фрагмент до разделителя или после него. Оба варианта строятся на связке СтрНайти плюс Лев или Сред. Для фрагмента до разделителя: Лев(Строка, Позиция - 1). Для фрагмента после: Сред(Строка, Позиция + СтрДлина(Разделитель)).
Строка = "Иванов И.И.:менеджер";
Поз = СтрНайти(Строка, ":");
Если Поз > 0 Тогда
ФИО = Лев(Строка, Поз - 1); // "Иванов И.И."
Должность = Сред(Строка, Поз + 1); // "менеджер"
Иначе
// разделителя нет — строка целиком относится к первой части
ФИО = Строка;
Должность = "";
КонецЕсли;
Обратите внимание на смещение: позиция указывает на сам разделитель, поэтому для левой части берём на один символ меньше, а для правой начинаем на длину разделителя дальше. Если разделитель состоит из нескольких символов (например, « - » с пробелами), смещение вычисляется через СтрДлина(Разделитель), а не жёстко заданной единицей.
- 1Найдите позицию разделителя через СтрНайти
- 2Проверьте, что позиция больше нуля — разделитель существует
- 3Извлеките левую часть: Лев(Строка, Позиция - 1)
- 4Извлеките правую часть: Сред(Строка, Позиция + СтрДлина(Разделитель))
- 5Уберите краевые пробелы через СокрЛП при необходимости
Разбор строки с несколькими разделителями через СтрРазделить
Когда в строке несколько одинаковых разделителей — CSV-подобные данные, перечни через запятую, полный путь через «\» — вручную искать каждое вхождение неудобно. Функция СтрРазделить(Строка, Разделитель) возвращает массив частей, из которого элементы берутся по индексу. Индексы массива, в отличие от позиций в строке, начинаются с нуля.
Строка = "001;Кабель ВВГ 3х2.5;м;150";
Части = СтрРазделить(Строка, ";");
Артикул = Части[0]; // "001"
Наименование = Части[1]; // "Кабель ВВГ 3х2.5"
Единица = Части[2]; // "м"
Количество = Число(Части[3]); // 150
Перед обращением к элементу по индексу проверяйте размер массива: если в исходной строке оказалось меньше разделителей, чем ожидалось, обращение к несуществующему индексу вызовет ошибку выполнения. Безопасный шаблон — сравнить Части.Количество() с требуемым числом полей.
Обратная задача — склеить массив строк в одну через разделитель — решается функцией СтрСоединить(Массив, Разделитель). Пара «СтрРазделить / СтрСоединить» покрывает большинство сценариев обмена данными в текстовых форматах без ручного посимвольного разбора.
Обработка пробелов и невидимых символов
Реальные данные из файлов, штрихкодов и пользовательского ввода почти всегда содержат лишние пробелы по краям. После извлечения фрагмента применяйте СокрЛП (убирает пробелы слева и справа) или СокрЛ / СокрП по отдельности. Без этого сравнение извлечённого значения с эталоном может неожиданно не сработать: «АБ-123» и «АБ-123 » — разные строки.
Отдельная ловушка — неразрывные пробелы и символы табуляции, которые СокрЛП в ряде случаев обрабатывает, но визуально в отладчике они неотличимы от обычных пробелов. Если строка «не чистится», проверьте коды символов через КодСимвола и при необходимости замените проблемные символы через СтрЗаменить до извлечения фрагмента.
Проверка результата и граничные случаи
Надёжный код извлечения подстроки всегда отвечает на три вопроса: что будет, если строка пустая; что будет, если разделитель не найден; что будет, если искомый фрагмент оказался короче ожидаемого. Пустая строка — штатная ситуация для необязательных реквизитов, и Лев("", 5) вернёт пустую строку без ошибки, но последующая логика (например, поиск по справочнику) должна это учитывать.
Для отладки используйте СтрДлина и вывод промежуточных значений через Сообщить или точку останова в конфигураторе. Быстрый способ убедиться, что позиция найдена верно: вывести Сред(Строка, Позиция, 1) — должен вернуться сам разделитель.
Как проверить результат
СтрНайти вернула число больше нуля
Вернулся 0 — разделителя нет, извлекать фрагмент нельзя
Совпадает с ожидаемой длиной значения
Фрагмент короче или пустой — проверьте смещение и исходные данные
Сред(Строка, Позиция, 1) равен разделителю
Вернулся другой символ — позиция рассчитана неверно
Совпадает после СокрЛП
Не совпадает — ищите скрытые пробелы или различия регистра
FAQ: частые вопросы о работе с подстроками в 1С
Как получить первый символ строки?
Используйте Лев(Строка, 1) или Сред(Строка, 1, 1) — оба варианта вернут первый символ. Для пустой строки результатом будет пустая строка, ошибки не возникнет.
Как удалить первые N символов из строки?
Примените Сред(Строка, N + 1) без третьего параметра — вернутся все символы начиная с позиции N+1, то есть строка без первых N символов. Если строка короче N, результат будет пустым.
Что вернёт СтрНайти, если подстрока не найдена?
Ноль. Это не ошибка выполнения, а нормальное возвращаемое значение, поэтому перед использованием позиции в Лев или Сред всегда проверяйте условие Позиция > 0.
Как извлечь текст между двумя разделителями?
Найдите позицию первого разделителя, от него — позицию второго через СтрНайти с параметром начальной позиции поиска, затем возьмите Сред(Строка, Позиция1 + ДлинаРазделителя, Позиция2 - Позиция1 - ДлинаРазделителя). Для строк с повторяющимися разделителями проще использовать СтрРазделить и взять нужный элемент массива.
Учитывается ли регистр при поиске подстроки?
Да, СтрНайти различает регистр. Если регистр не гарантирован, приведите копию строки и искомую подстроку к одному регистру через НРег или ВРег, найдите позицию в копии, а фрагмент извлекайте из исходной строки — позиции совпадут.
Как получить последние символы строки неизвестной длины?
Функция Прав(Строка, N) сама работает от конца строки, знать полную длину не требуется. Если запрошенное N больше длины строки, вернётся вся строка целиком без ошибки.
Что важно запомнить
Часть строки в 1С извлекают функции Лев, Прав и Сред, позицию разделителя даёт СтрНайти, а строки с несколькими разделителями разбирает СтрРазделить. Позиции считаются с 1, нулевой результат СтрНайти проверяется всегда, а извлечённый фрагмент перед сравнением очищается через СокрЛП.