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

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

Как разобрать строку в 1С 8: практическое руководство

Как разобрать строку в 1С 8: СтрРазделить, СтрНайти, Сред, обработка CSV и ФИО, проверка результата, типичные ошибки и готовые примеры кода.

Разбор строк — одна из самых частых задач при разработке на платформе 1С:Предприятие 8. ФИО из одного поля нужно разложить на фамилию, имя и отчество, строку из CSV-файла — на колонки, артикул вида «ТОВ-00123-РФ» — на составные части. Для каждой из этих задач во встроенном языке есть подходящий инструмент, и выбор зависит от структуры исходных данных.

Основные способы разбора: функция СтрРазделить() для строк с разделителем, связка СтрНайти(), Лев(), Сред(), Прав() для позиционного извлечения, а для сложных шаблонов — регулярные выражения через COM-объект VBScript.RegExp или внешние компоненты. Платформа 8.3.6 и новее предоставляет СтрРазделить() как штатный механизм, поэтому самописные циклы посимвольного разбора сегодня нужны редко.

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

Разбор строки функцией СтрРазделить

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

СтрокаДанных = "Иванов;Иван;Иванович";

Части = СтрРазделить(СтрокаДанных, ";", Ложь);

Если Части.Количество() = 3 Тогда

Фамилия = Части[0];

Имя = Части[1];

Отчество = Части[2];

Иначе

Сообщить("Неверный формат строки: ожидалось 3 части");

КонецЕсли;

Третий параметр критичен при разборе данных из внешних систем. Строка "А;;Б" при ВключатьПустые = Истина даст массив из трёх элементов («А», «», «Б»), а при Ложь — только два. Если колонки в файле позиционно значимы, пустые значения нужно сохранять, иначе сместятся все последующие поля.

Помните, что разделитель — это набор символов. Вызов СтрРазделить(Строка, "||") разобьёт строку по одиночному символу «|», а не по двойному. Если в данных встречается составной разделитель вроде «~~», предварительно замените его через СтрЗаменить() на одиночный редкий символ, а затем разбивайте.

Позиционный разбор: СтрНайти, Лев, Сред, Прав

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

Артикул = "ТОВ-00123-РФ";

ПозицияДефиса = СтрНайти(Артикул, "-");

Если ПозицияДефиса > 0 Тогда

Префикс = Лев(Артикул, ПозицияДефиса - 1); // "ТОВ"

Остаток = Сред(Артикул, ПозицияДефиса + 1); // "00123-РФ"

Иначе

Сообщить("Разделитель не найден в артикуле");

КонецЕсли;

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

Проверка Позиция > 0 обязательна: если разделитель не найден, Лев(Строка, -1) и подобные вызовы приведут к ошибке. Это самая частая причина падения обработок загрузки на «кривых» строках.

Разбор CSV и строк из файлов обмена

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

Чтение = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);

СтрокаФайла = Чтение.ПрочитатьСтроку();

Пока СтрокаФайла <> Неопределено Цикл

СтрокаФайла = СокрЛП(СтрокаФайла);

Если Не ПустаяСтрока(СтрокаФайла) Тогда

Колонки = СтрРазделить(СтрокаФайла, ";", Истина);

Если Колонки.Количество() >= 5 Тогда

// обработка колонок

Иначе

Сообщить("Пропущена строка: " + СтрокаФайла);

КонецЕсли;

КонецЕсли;

СтрокаФайла = Чтение.ПрочитатьСтроку();

КонецЦикла;

Чтение.Закрыть();

Отдельная сложность — значения, содержащие разделитель внутри кавычек, например "Иванов; И. И.";45;Москва. Простая СтрРазделить() такой случай не обработает корректно: кавычки нужно снимать отдельной логикой. Если формат файла допускает вложенные разделители, надёжнее использовать ЧтениеXML/ЧтениеJSON при возможности выбора формата или специализированный построчный парсер с учётом кавычек.

При загрузке больших файлов избегайте конкатенации строк в цикле через + — это замедляет обработку. Для накопления результата используйте массив строк и СтрСоединить() в конце.

Порядок действий при загрузке строк из файла
  1. 1
    Откройте файл через ЧтениеТекста с явно указанной кодировкой
  2. 2
    Прочитайте строку и удалите краевые пробелы через СокрЛП
  3. 3
    Пропустите пустые строки через ПустаяСтрока
  4. 4
    Разбейте строку через СтрРазделить с включением пустых элементов
  5. 5
    Проверьте Количество() элементов до обращения по индексам
  6. 6
    При несоответствии формату запишите строку в протокол и продолжите цикл

Разбор ФИО, адресов и других «человеческих» данных

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

Перед разбором нормализуйте пробелы: циклом СтрЗаменить(Строка, " ", " ") или регулярным выражением сожмите множественные пробелы до одного. После разбора каждую часть обработайте СокрЛП(). Если отчество может отсутствовать, определяйте структуру по количеству элементов: 2 части — фамилия и имя, 3 — полное ФИО.

Адреса и составные наименования разбирать жёстким шаблоном опасно: «ул. Ленина, д. 5, кв. 12» и «Ленина 5-12» дадут разную структуру. Для таких данных лучше сохранять строку целиком, а разбор выполнять только под конкретную задачу с протоколированием нераспознанных случаев. Если адреса нужно структурировать массово, рассмотрите типовые механизмы контактной информации БСП — там уже реализован разбор по полям.

Типичные ошибки при разборе строк
01
Обращение к Части[2] без проверки Количество() — ошибка выполнения на неполных данных
02
Разбор ФИО без сжатия двойных пробелов — пустые элементы сдвигают структуру
03
Игнорирование неразрывных пробелов из Excel — строка выглядит нормально, но не сравнивается и не разбивается
04
Предположение, что разделитель в СтрРазделить — целая строка, а не набор символов
05
Сохранение в базу результата без СокрЛП — дубли в справочниках из-за пробелов

Регулярные выражения для сложных шаблонов

Когда структура строки описывается шаблоном — например, «буквы, дефис, шесть цифр» — удобнее регулярные выражения. Во встроенном языке 1С нет штатного механизма RegExp, поэтому традиционно используют COM-объект VBScript.RegExp (доступен на Windows-клиенте и сервере под Windows) или внешние компоненты.

RegExp = Новый COMОбъект("VBScript.RegExp");

RegExp.Pattern = "^[А-ЯA-Z]{3}-(\d{6})$";

RegExp.IgnoreCase = Истина;

Если RegExp.Test(Артикул) Тогда

Совпадения = RegExp.Execute(Артикул);

НомерЧасть = Совпадения.Item(0).SubMatches(0); // "001234"

Иначе

Сообщить("Артикул не соответствует шаблону");

КонецЕсли;

Ограничения подхода: COM-объект недоступен на Linux-сервере, в веб-клиенте и в мобильной платформе. Если решение должно быть кроссплатформенным, регулярные выражения реализуют через внешние компоненты по технологии Native API или переписывают логику на комбинацию строковых функций и посимвольной проверки. Для простых шаблонов проверку можно выполнить и без RegExp — циклом по символам с анализом кодов.

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

Сравнение способов разбора строк

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

Строки с известным разделителем: CSV, ФИО, списки. Быстро и просто, но не справляется с вложенными разделителями в кавычках

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

Извлечение одной-двух частей по позиции разделителя. Гибко, но при множестве частей код становится громоздким

RegExp (COM)

Сложные шаблоны и валидация формата. Ограничение: только Windows-окружение, медленнее штатных функций

ЧтениеXML / ЧтениеJSON

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

Проверка результата и производительность

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

Преобразование строк в числа и даты делайте аккуратно. Прямое присваивание Число(СтрокаЧисла) выбросит исключение на «12,5 кг». Для безопасного преобразования используйте ОписаниеТипов с методом ПривестиЗначение() — он вернёт значение по умолчанию вместо ошибки, либо оборачивайте преобразование в Попытка...Исключение с записью в протокол.

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

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

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

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

Совпадает с ожидаемым числом полей

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

Меньше или больше — строка не соответствует формату, обрабатывать нельзя

Содержимое каждой части
Норма

Нет краевых пробелов, значения проходят валидацию типа

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

Пустые строки там, где ожидались данные; непреобразуемые числа

Записанные данные в базе
Норма

Значения совпадают с исходной строкой, нет дублей

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

Смещённые поля, обрезанные значения, дубли из-за пробелов

Частые вопросы по разбору строк в 1С

Чем заменить СтрРазделить, если платформа старше 8.3.6?

Используйте цикл со СтрНайти: находите позицию разделителя, забирайте часть через Лев(), обрезайте строку через Сред() и повторяйте, пока разделитель не перестанет находиться. Готовые универсальные функции разбора есть в Библиотеке стандартных подсистем — если конфигурация на БСП, вызывайте СтрРазделить из общего модуля СтроковыеФункцииКлиентСервер.

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

Штатные функции такой случай не обрабатывают. Варианты: использовать формат с экранированием (кавычки в CSV) и писать парсер с учётом кавычек; заменить служебные вхождения разделителя на уникальный маркер до разбора; лучше всего — договориться о формате JSON или XML, где вложенность поддерживается штатно.

Почему строка из Excel не разбивается, хотя разделитель виден?

Чаще всего причина в неразрывных пробелах (код 160) или невидимых служебных символах, скопированных из Excel. Очистите строку: СтрЗаменить(Строка, Символ(160), " ") и СокрЛП. Также проверьте, что разделитель в файле действительно тот символ, который вы ожидаете, — точка с запятой и запятая визуально похожи в некоторых шрифтах.

Как из строки «1250,50 руб.» получить число?

Уберите всё лишнее: СтрЗаменить для удаления «руб.» и пробелов, затем приведите запятую к точке или наоборот в зависимости от региональных настроек. Преобразуйте через ОписаниеТипов("Число").ПривестиЗначение(ПодготовленнаяСтрока) — при невозможности преобразования получите 0 вместо ошибки, что удобно для массовой загрузки с протоколированием.

Работает ли VBScript.RegExp на сервере под Linux?

Нет, COM-объекты доступны только в Windows-окружении. На Linux-сервере код с Новый COMОбъект("VBScript.RegExp") завершится ошибкой. Для кроссплатформенного решения используйте внешние компоненты Native API с реализацией регулярных выражений или переписывайте проверку на штатные строковые функции и посимвольный анализ.

Что быстрее: СтрРазделить или цикл со СтрНайти?

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

Итог

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

Разбивайте строки через СтрРазделить, извлекайте по позиции через СтрНайти с Лев/Сред/Прав, сложные шаблоны обрабатывайте RegExp с учётом ограничений платформы. Всегда проверяйте количество элементов и очищайте входные данные от лишних пробелов — большинство ошибок разбора связано не с функциями, а с качеством исходных строк.