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

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

Как обрезать строку до символа в 1С

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

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

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

Материал применим к управляемым и обычным формам, тонкому и толстому клиенту — функции работы со строками одинаковы во всех режимах платформы 1С:Предприятие 8.

Базовый приём: СтрНайти и Лев

Функция СтрНайти(Строка, Подстрока) возвращает позицию первого вхождения подстроки, начиная с 1. Если символ не найден, возвращается 0. Функция Лев(Строка, ЧислоСимволов) берёт указанное количество символов с начала строки. Комбинируя их, получаем часть строки до разделителя.

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

Обратите внимание на вычитание единицы: Позиция - 1 означает, что сам разделитель в результат не попадает. Если нужно оставить символ в обрезанной строке, используйте Лев(Строка, Позиция).

Проверка Если Позиция > 0 обязательна. Без неё при отсутствии символа Лев(Строка, -1) вызовет ошибку выполнения, а в некоторых сценариях — молча неверные данные, что ещё хуже.

Как взять часть строки после символа

Обратная задача — отрезать начало строки и оставить то, что идёт после разделителя. Здесь вместо Лев используется Сред: функция Сред(Строка, НачальнаяПозиция) без третьего параметра возвращает всё от указанной позиции до конца строки.

bsl
Артикул = "ТМЦ-001234";
Позиция = СтрНайти(Артикул, "-");
Если Позиция > 0 Тогда
    НомерЧасть = Сред(Артикул, Позиция + 1);
Иначе
    НомерЧасть = Артикул;
КонецЕсли;
// НомерЧасть = "001234"

Конструкция Позиция + 1 пропускает сам разделитель. Если разделитель состоит из нескольких символов (например, "::"), добавляйте его длину: Сред(Строка, Позиция + СтрДлина(Разделитель)).

Универсальная функция для повторного использования

Если обрезка нужна в нескольких местах, вынесите логику в общий модуль. Это избавит от дублирования проверок и упростит сопровождение.

bsl
Функция СтрокаДоСимвола(Строка, Символ) Экспорт
    Позиция = СтрНайти(Строка, Символ);
    Если Позиция = 0 Тогда
        Возврат Строка;
    КонецЕсли;
    Возврат Лев(Строка, Позиция - 1);
КонецФункции

Поиск с конца строки: последнее вхождение символа

По умолчанию СтрНайти ищет первое вхождение слева. Но часто нужен последний разделитель: например, в пути \\server\docs\file.txt имя файла отделено последним обратным слэшем, а в строке 10.5.3 последняя точка отделяет минорную версию.

Для поиска с конца у СтрНайти есть третий параметр — направление поиска. Передайте значение НаправлениеПоиска.СКонца:

Тот же приём работает для извлечения расширения файла: ищите последнюю точку и берите Сред от неё. Учтите граничный случай — если точка в пути есть только в имени каталога, а у файла расширения нет, результат будет неверным, поэтому для путей надёжнее использовать объект Файл и его свойство Расширение.

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

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

bsl
ФИО = "Петров Пётр Петрович";
Части = СтрРазделить(ФИО, " ");
// Части[0] = "Петров", Части[1] = "Пётр", Части[2] = "Петрович"

У СтрРазделить есть второй параметр — включать ли пустые строки. По умолчанию он равен Истина, то есть два разделителя подряд дадут пустой элемент массива. Если пустые части не нужны, передайте Ложь. Это важно при разборе данных из внешних источников, где разделители часто дублируются.

Обратная операция — склейка массива строк через разделитель — выполняется функцией СтрСоединить(Массив, ";").

Какой способ выбрать

СтрНайти + Лев/Сред

Нужна одна часть до или после символа. Полный контроль над обработкой отсутствия разделителя.

СтрРазделить

Нужны все части строки с повторяющимся разделителем. Меньше кода, но требуется проверка числа элементов массива.

СтрНайти с НаправлениеПоиска.СКонца

Разделитель встречается несколько раз, а нужна граница у последнего вхождения — пути, расширения, версии.

Обрезка в запросах 1С

Иногда строку нужно обрезать прямо в запросе — например, сгруппировать данные по префиксу номенклатуры. В языке запросов есть функции ПОДСТРОКА и ГДЕ ... ПОДОБНО, но прямого аналога СтрНайти нет. Поэтому распространены два подхода.

Первый — отбор по шаблону: ГДЕ Артикул ПОДОБНО "ТМЦ-%". Здесь символ % означает любую последовательность символов, а _ — один произвольный символ. Спецсимволы в шаблоне экранируются через конструкцию СПЕЦСИМВОЛ.

Второй — фиксированная обрезка через ПОДСТРОКА(Артикул, 1, 3), если позиция разделителя постоянна. Если позиция плавает, обрезку до символа надёжнее выполнять в коде после выборки: выгрузить результат запроса и обработать каждую строку функцией из общего модуля.

Если обрезка до символа нужна регулярно в отчётах и отборах, подумайте о хранении отдельной части строки в отдельном реквизите и заполнении его при записи объекта. Это быстрее, чем вычисления в каждом запросе, и позволяет строить индексы.
ПЗ
Практическое замечание

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

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

Типичные ошибки
01
Нет проверки Позиция > 0 — падение с ошибкой при отсутствии разделителя в данных
02
Забыто -1 или +1 — разделитель попадает в результат или теряется символ данных
03
Поиск первого вхождения вместо последнего в путях файлов — неверное имя файла при вложенных каталогах
04
Игнорирование регистра — разделитель в другом регистре не находится
05
Использование СтрРазделить без проверки количества элементов — обращение к несуществующему индексу массива
Порядок безопасной реализации
  1. 1
    Определите, нужна часть до символа, после него или все части строки
  2. 2
    Выберите функции: СтрНайти+Лев, СтрНайти+Сред или СтрРазделить
  3. 3
    Добавьте обработку случая, когда разделитель не найден
  4. 4
    Протестируйте на граничных строках: пустая, без разделителя, разделитель в начале и в конце
  5. 5
    При повторном использовании вынесите код в общий модуль

FAQ

Как обрезать строку до второго вхождения символа?

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

Чем отличается СтрНайти от устаревшей Найти?

Функция Найти() существует для совместимости со старым кодом и ищет подстроку с начала строки. СтрНайти — современный вариант с расширенными параметрами: направление поиска, начальная позиция и номер вхождения. В новом коде используйте СтрНайти.

Как убрать пробелы по краям после обрезки?

Оберните результат в СокрЛП(): СокрЛП(Лев(Строка, Позиция - 1)). Это удалит пробелы и неразрывные пробелы в начале и конце результата, что часто нужно при разборе данных из Excel или текстовых файлов.

Работает ли этот код на клиенте и на сервере?

Да, функции работы со строками (СтрНайти, Лев, Сред, СтрРазделить) доступны в любом контексте: тонкий клиент, толстый клиент, веб-клиент, сервер. Директивы компиляции для них не требуются.

Как обрезать строку до символа, игнорируя регистр?

Найдите позицию в копии строки, приведённой к одному регистру: Позиция = СтрНайти(ВРег(Строка), ВРег(Символ)), а затем применяйте Лев или Сред к исходной строке. Позиции совпадут, так как ВРег не меняет длину строки.

Что вернёт Лев(Строка, 0)?

Пустую строку. Это безопасное поведение: если разделитель стоит первым символом и вы вычли единицу из позиции, ошибки не будет — просто результат до разделителя окажется пустым. Учитывайте это при проверках на пустоту.

Итог

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

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