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

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

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

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

Парсинг строк — одна из самых частых задач при разработке и доработке конфигураций 1С: разобрать ФИО на части, извлечь номер из представления документа, обработать строку из CSV-файла или ответ веб-сервиса. Встроенный язык 1С предоставляет несколько инструментов для этого, и выбор зависит от структуры исходных данных и версии платформы.

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

Для сложных шаблонов используют либо комбинацию строковых функций, либо объект VBScript.RegExp на Windows, либо обработку на стороне внешних компонент. Ниже разобраны рабочие подходы с готовым кодом.

Разбор строки по разделителю через СтрРазделить

Функция СтрРазделить — основной инструмент парсинга в современных версиях платформы (доступна начиная с 8.3.6). Она принимает исходную строку, разделитель и необязательный признак включения пустых строк, а возвращает массив элементов.

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

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

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

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

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

Третий параметр ВключатьПустые критичен, когда позиция элемента имеет значение. Например, в строке "Иванов;;Иванович" при значении Истина массив будет содержать три элемента, а при Ложь — только два, и индексы сместятся. Для обменных форматов с фиксированной структурой всегда включайте пустые значения.

Перед обращением к элементу массива проверяйте его размер через Части.Количество(). Обращение к несуществующему индексу вызовет ошибку исполнения и прервёт обработку — типичная причина падения загрузок из файлов с «кривыми» строками.

Безопасный порядок разбора строки
  1. 1
    Проверьте строку на пустоту: ПустаяСтрока(СтрокаДанных)
  2. 2
    Убедитесь, что разделитель присутствует: СтрНайти(СтрокаДанных, ";") > 0
  3. 3
    Выполните СтрРазделить с нужным признаком включения пустых
  4. 4
    Проверьте Части.Количество() перед обращением по индексу
  5. 5
    Обрежьте пробелы каждого элемента через СокрЛП

Поиск позиции подстроки: СтрНайти и извлечение фрагментов

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

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

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

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

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

КонецЕсли;

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

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

Разбор многострочного текста

Функция СтрЧислоСтрок и СтрПолучитьСтроку работают с текстом, где строки разделены символом переноса. Это удобно для обработки содержимого текстовых файлов или многострочных полей.

Для НомерСтроки = 1 По СтрЧислоСтрок(Текст) Цикл

ТекущаяСтрока = СтрПолучитьСтроку(Текст, НомерСтроки);

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

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

// обработка частей

КонецЕсли;

КонецЦикла;

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

Готовые функции из БСП и типовых конфигураций

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

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

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

Сложные шаблоны: регулярные выражения и их ограничения

Встроенный язык 1С не имеет нативной поддержки регулярных выражений. На Windows-сервере или толстом клиенте под Windows можно использовать COM-объект VBScript.RegExp:

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

RegExp.Pattern = "\d+";

RegExp.Global = Истина;

Результат = RegExp.Execute("Заказ 123 от 456");

У этого подхода жёсткое ограничение: COM-объект недоступен на Linux-сервере и в веб-клиенте, поэтому для кроссплатформенных решений он не подходит. Альтернативы — внешние компоненты по технологии Native API, разбор через ЧтениеXML/ЧтениеJSON для структурированных данных или перенос сложной логики на сторону внешнего сервиса.

Парсинг JSON и XML вместо ручного разбора

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

Чтение = Новый ЧтениеJSON;

Чтение.УстановитьСтроку(СтрокаJSON);

Данные = ПрочитатьJSON(Чтение);

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

Значение = Данные.НомерДокумента;

Для CSV-файлов штатного парсера нет, но если поля могут содержать разделитель внутри кавычек, простой СтрРазделить даст неверный результат. В таком случае пишут посимвольный разбор с отслеживанием состояния «внутри кавычек» либо используют готовые обработки загрузки табличных данных.

Сравнение способов парсинга

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

Строка с фиксированным разделителем. Быстро и просто, но не справляется с кавычками в CSV и вложенными структурами.

СтрНайти + Сред

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

ПрочитатьJSON / ПрочитатьXML

Структурированные данные обмена. Единственный надёжный вариант для JSON и XML.

VBScript.RegExp

Сложные шаблоны поиска. Только Windows, не работает на Linux-сервере и в веб-клиенте.

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

После разбора результат нужно валидировать: количество частей соответствует ожидаемому формату, числовые поля реально преобразуются в число, даты — в дату. Для безопасного преобразования используйте ОписаниеТипов с методом ПривестиЗначение — он не выбрасывает исключение, а возвращает значение по умолчанию при невозможности приведения.

Типичные ошибки
01
Обращение к Части[2] без проверки Части.Количество() — ошибка исполнения на неполных строках
02
Разбор CSV с кавычками через СтрРазделить — поля с запятой внутри разваливаются
03
Ручной парсинг JSON строковыми функциями — ломается на экранированных символах
04
Забытый СокрЛП — лишние пробелы мешают сравнению и поиску в базе
05
Использование COM RegExp на сервере Linux — код падает при исполнении

Ещё одна группа ошибок связана с региональными настройками: при преобразовании строки в число разделитель дробной части может интерпретироваться по-разному. Если данные приходят из внешних источников, приводите разделитель к единому виду через СтрЗаменить до преобразования.

Итог

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

Для строк с разделителем используйте СтрРазделить с проверкой количества элементов, для поиска фрагментов — СтрНайти вместе с Лев, Прав и Сред. JSON и XML разбирайте только штатными чтениями, а регулярные выражения через COM — с учётом ограничения на Windows. Любой результат парсинга валидируйте перед записью в базу.

Частые вопросы

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

Штатной функции с набором разделителей нет. Практичный приём — сначала заменить все альтернативные разделители на один через цепочку СтрЗаменить, затем применить СтрРазделить. Например, привести запятые и точки с запятой к одному символу и разбить по нему.

Как извлечь только цифры из строки?

Переберите символы в цикле и проверяйте вхождение каждого в строку "0123456789" через СтрНайти, накапливая результат. Встроенной функции для этого в языке нет; на Windows можно решить задачу одним выражением через VBScript.RegExp с шаблоном \D и заменой на пустую строку.

Чем отличается СтрРазделить от СтрПолучитьСтроку?

СтрРазделить работает с произвольным разделителем и возвращает массив подстрок. СтрПолучитьСтроку работает только с переносами строк и возвращает одну строку по номеру из многострочного текста — это инструменты для разных задач.

Как распарсить строку в 1С версии 8.2 или младше 8.3.6?

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

Почему СтрРазделить возвращает меньше элементов, чем ожидалось?

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

Можно ли парсить строку запросом, без кода?

Частично. В языке запросов есть функция ПОДСТРОКА и оператор ПОДОБНО для фильтрации по шаблону, но полноценного разбиения строки на массив в запросе нет. Для сложного разбора данные выгружают из запроса и обрабатывают в коде.