Разработка и Конфигурация · 11 мин
Что такое подстрока в 1С и как с ней работать
Подстрока в 1С — часть строки, извлекаемая функциями Лев, Прав, Сред. Синтаксис, примеры кода, поиск подстроки, типичные ошибки и ответы на вопросы.
Подстрока в 1С — это часть строки, выделенная из исходного строкового значения по заданным правилам: с начала, с конца, из середины или по позиции найденного фрагмента. Сама по себе подстрока не является отдельным типом данных — это результат работы строковых функций встроенного языка: Лев, Прав, Сред, а также СтрНайти для определения позиции вхождения.
На практике выделение подстрок требуется постоянно: разобрать артикул на префикс и номер, извлечь код из наименования номенклатуры, отрезать лишние символы при загрузке данных из Excel или CSV, сформировать сокращённое представление документа. Почти любая обработка по обмену данными так или иначе использует эти функции.
Важно понимать, что строки в 1С неизменяемы: функции не модифицируют исходную строку, а возвращают новое значение. Нумерация символов начинается с 1, а не с 0, как во многих других языках — это частый источник ошибок у тех, кто пришёл из других сред разработки.
Какие функции извлекают подстроку
Во встроенном языке 1С три базовые функции выделения подстроки, и каждая решает свою задачу. Лев(Строка, ЧислоСимволов) возвращает заданное количество символов с начала строки. Прав(Строка, ЧислоСимволов) — с конца. Сред(Строка, НачальнаяПозиция, ЧислоСимволов) — из произвольного места, начиная с указанной позиции.
Дополнительно используется СтрДлина(Строка), возвращающая длину строки — без неё сложно вычислить позиции для Сред и Прав. И СтрНайти(Строка, ПодстрокаПоиска), которая возвращает позицию первого вхождения подстроки или 0, если вхождение не найдено.
| Функция | Что возвращает | Типичный сценарий |
|---|---|---|
Лев(Строка, N) | Первые N символов | Префикс номера документа |
Прав(Строка, N) | Последние N символов | Код из конца артикула |
Сред(Строка, Поз, N) | N символов с позиции Поз | Фрагмент между разделителями |
СтрНайти(Строка, Подстр) | Позицию вхождения или 0 | Поиск разделителя |
СтрДлина(Строка) | Длину строки | Вычисление границ вырезки |
Синтаксис и примеры кода
Рассмотрим базовые приёмы на конкретных примерах. Пусть есть артикул вида «ТОВ-001234-RU», и нужно извлечь его части:
Артикул = "ТОВ-001234-RU";
Префикс = Лев(Артикул, 3); // "ТОВ"
Суффикс = Прав(Артикул, 2); // "RU"
НомерЧасть = Сред(Артикул, 5, 6); // "001234"
Обратите внимание на третью строку: позиция 5 — это первый символ после дефиса, потому что нумерация идёт с единицы. Если бы нумерация начиналась с нуля, позиция была бы 4. Эту разницу нужно держать в голове при переносе алгоритмов из других языков.
Если запрошенная длина в Лев или Прав больше длины строки, функция просто вернёт всю строку целиком — ошибки не будет. Это удобно, но иногда маскирует логические ошибки: вы ожидаете строку из 10 символов, а получаете из 3, и дальше по коду это всплывёт в неожиданном месте.
Артикул = "ТОВ-001234-RU";
ПозицияДефиса = СтрНайти(Артикул, "-");
Если ПозицияДефиса > 0 Тогда
Префикс = Лев(Артикул, ПозицияДефиса - 1);
КонецЕсли;Поиск подстроки и вырезание по разделителю
На практике позиции подстрок редко известны заранее — чаще они определяются через разделитель: дефис, запятую, пробел. Типовой приём — найти позицию разделителя функцией СтрНайти и от неё вычислить границы вырезки.
Строка = "Иванов Иван Иванович";
ПозицияПробела = СтрНайти(Строка, " ");
Если ПозицияПробела > 0 Тогда
Фамилия = Лев(Строка, ПозицияПробела - 1); // "Иванов"
Остаток = Сред(Строка, ПозицияПробела + 1); // "Иван Иванович"
КонецЕсли;
Ключевой момент — проверка ПозицияПробела > 0. Если разделитель не найден, СтрНайти вернёт 0, и без проверки вы получите некорректные вырезки: Лев(Строка, -1) вызовет ошибку, а Сред(Строка, 1) вернёт всю строку, что может быть не тем, что вы ожидали.
У СтрНайти есть необязательные параметры: направление поиска (с начала или с конца) и номер вхождения. Поиск с конца полезен, когда разделителей несколько и нужен последний — например, для отделения расширения файла от имени.
Разбор строки на массив подстрок
Когда строку нужно разрезать не на две части, а на множество — например, строку CSV с десятком полей — перебирать разделители вручную через СтрНайти неудобно. Для этого есть функция СтрРазделить(Строка, Разделитель), которая возвращает массив подстрок.
СтрокаCSV = "Мука;Сахар;Соль";
Массив = СтрРазделить(СтрокаCSV, ";");
// Массив[0] = "Мука", Массив[1] = "Сахар", Массив[2] = "Соль"
Обратная операция — СтрСоединить(Массив, Разделитель) — склеивает массив подстрок обратно в одну строку. Эта пара функций покрывает большинство задач по разбору и сборке составных строк: путей к файлам, списков значений, служебных маркеров.
Учтите, что СтрРазделить по умолчанию включает пустые подстроки: при разборе «а;;б» вы получите три элемента, средний — пустой. Если пустые значения не нужны, передайте вторым параметром Ложь.
- 1Определите разделитель и убедитесь, что он не встречается внутри самих данных
- 2Найдите позицию разделителя через СтрНайти или разбейте всю строку через СтрРазделить
- 3Проверьте, что разделитель найден (позиция больше 0) или массив содержит нужное число элементов
- 4Извлеките подстроки через Лев, Сред или по индексам массива
- 5Очистите результат от пробелов функцией СокрЛП перед дальнейшим использованием
Типичные ошибки при работе с подстроками
Самая частая ошибка — забыть, что нумерация символов начинается с 1. Разработчик, привыкший к нулевой индексации, пишет Сред(Строка, 0, 5) и получает либо ошибку, либо сдвиг на один символ, который потом долго ищется в отладке.
Вторая группа ошибок связана с пробелами и невидимыми символами. Строки, загруженные из файлов или скопированные из внешних систем, часто содержат пробелы по краям и неразрывные пробелы внутри. Сравнение подстроки «АРТ» с реальным фрагментом « АРТ» даст ложь, хотя визуально всё выглядит одинаково. Перед разбором применяйте СокрЛП, а при подозрении на неразрывные пробелы — замену через СтрЗаменить с символом с кодом 160.
Третья типичная проблема — регистр. СтрНайти чувствительна к регистру: «арт» в строке «АРТ-123» не найдётся. Если регистр данных не гарантирован, приводите обе строки к одному регистру через ВРег или НРег перед поиском.
Производительность и ограничения
Строковые функции в 1С работают быстро на обычных данных, но в циклах по большим объёмам — сотни тысяч строк при загрузке прайсов или выгрузке отчётов — стоит помнить о нескольких моментах. Каждая операция создаёт новую строку в памяти, поэтому многократная склейка через Строка = Строка + Кусок в цикле работает медленнее, чем сборка через массив с последующим СтрСоединить.
Для сложных шаблонов поиска — например, «найти все вхождения кода из букв и цифр произвольной длины» — базовых функций недостаточно. В толстом клиенте и на сервере можно задействовать регулярные выражения через COM-объект VBScript.RegExp (только Windows) или реализовать разбор вручную посимвольно. Но для большинства учётных задач комбинации СтрНайти, Лев, Сред и СтрРазделить достаточно.
Отдельное ограничение — строки неограниченной длины в запросах. Если вы работаете с подстрокой внутри запроса (функция ПОДСТРОКА языка запросов), помните, что сравнение и соединение по неограниченным строкам невозможны — сначала их нужно привести к фиксированной длине через ВЫРАЗИТЬ.
Сравнение подходов
Подходят, когда позиции известны или вычисляются просто. Ограничение — нужно вручную контролировать границы
Универсальный способ для строк с разделителем. Требует обязательной проверки, что разделитель найден
Лучший выбор для множества однотипных частей (CSV, списки). Не подходит, если разделитель может быть внутри данных
Для сложных шаблонов поиска. Ограничение — зависимость от платформенного окружения и более сложный код
Как проверить результат
После написания кода разбора строки проверьте его на граничных случаях: пустая строка, строка без разделителя, строка, начинающаяся или заканчивающаяся разделителем, строка из одного разделителя. Именно на таких данных всплывают ошибки, которые на «нормальных» значениях не видны.
Быстрый способ проверки — сообщить результат через Сообщить() с визуальными маркерами границ, например вывести подстроку в квадратных скобках: [АРТ]. Так сразу видно лишние пробелы и пустые значения, которые при обычном выводе незаметны.
Как проверить результат
СтрНайти вернула число больше 0
Вернулся 0 — разделителя нет, вырезка некорректна
Вывод в скобках [значение] без пробелов по краям
Видны пробелы или пустые скобки — нужна СокрЛП или проверка данных
Массив после СтрРазделить содержит ожидаемое число элементов
Элементов меньше — обращение по индексу вызовет ошибку
Обе строки приведены к одному регистру перед СтрНайти
Поиск не находит заведомо существующий фрагмент
Частые вопросы о подстроках в 1С
Чем подстрока отличается от строки в 1С?
Ничем на уровне типа данных: подстрока — это обычное значение типа «Строка», просто полученное как часть другой строки. Отдельного типа «подстрока» в платформе нет, термин описывает только происхождение значения.
Как удалить из строки найденную подстроку?
Проще всего функцией СтрЗаменить: СтрЗаменить(ИсходнаяСтрока, УдаляемыйФрагмент, "") вернёт строку без указанного фрагмента. Заменяются все вхождения, поэтому если нужно удалить только первое — сначала найдите его позицию через СтрНайти и соберите результат из Лев и Сред.
Что вернёт СтрНайти, если подстрока не найдена?
Ноль. Это значение обязательно нужно проверять перед использованием позиции в Лев, Прав или Сред, иначе получите либо ошибку выполнения, либо некорректный результат, который трудно отловить.
Как получить подстроку в запросе 1С?
В языке запросов есть функция ПОДСТРОКА(Поле, НачальнаяПозиция, Длина) — аналог Сред. Учтите, что для полей неограниченной длины её применение и последующие соединения ограничены: сначала приведите поле к фиксированной длине через ВЫРАЗИТЬ(Поле КАК Строка(N)).
Чувствителен ли поиск подстроки к регистру?
Да, СтрНайти различает регистр символов. Если регистр данных непредсказуем (например, введён пользователем), приведите обе строки к верхнему регистру функцией ВРег перед поиском — это стандартный приём для регистронезависимого сравнения.
Как разбить строку с разными разделителями?
Функция СтрРазделить принимает строку из нескольких символов-разделителей: СтрРазделить(Текст, ";,") разрежет и по точке с запятой, и по запятой. Если нужен разделитель из нескольких символов как единое целое, придётся использовать СтрНайти в цикле.
Что важно запомнить
Подстрока в 1С — результат функций Лев, Прав, Сред и разбора через СтрНайти или СтрРазделить. Нумерация символов с 1, исходная строка не меняется, результат СтрНайти всегда проверяйте на 0, а данные из внешних источников очищайте через СокрЛП и учитывайте регистр.