Как в 1С извлечь числа и очистить строку от динамических префиксов при парсинге текста?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При обработке текстовых файлов, выгрузок из сторонних систем или веб-страниц часто возникает задача выделения конкретных данных (чисел, артикулов, идентификаторов) из строк с переменным префиксом. Например, в строке присутствуют динамические фрагменты вида 2> 111222, 3> 222333 или теги lang=EN-US>, от которых невозможно избавиться простой заменой через СтрЗаменить из-за меняющейся нумерации. Разберем по шагам различные способы решения этой задачи: от базовых строковых функций платформы 1С до универсальных регулярных выражений и специализированных механизмов разбора.

Способ 1. Получение подстроки фиксированной длины (функция Прав)

Проанализируем простейший случай: если целевое число или идентификатор всегда имеет строго фиксированную длину (например, ровно 6 символов в конце строки), нам не требуется определять позицию префикса. Достаточно отсечь нужную часть с правого края.

Посмотрим на пример реализации:


// Предположим, что в переменной Стр3 находится значение "2> 111222"
ДлинаИдентификатора = 6;
Результат = СокрЛП(Прав(Стр3, ДлинаИдентификатора));

Ограничения способа: данный вариант подходит только в том случае, если длина целевых данных абсолютно стабильна. Если в файле встретятся числа разной разрядности или пробелы на конце строки, алгоритм вернет некорректный результат.

Способ 2. Поиск позиции разделителя (функции СтрНайти и Сред)

Если длина чисел может меняться, но после служебного символа (например, закрывающей скобки > или пробела) всегда следуют нужные данные, разберем позиционный поиск подстроки.

Рассмотрим вариант отсечения префикса по первому пробелу после служебных знаков:


ПозицияПробела = СтрНайти(СтрокаДанных, " "); // Для версий 8.2 и ранее используется функция Найти()
Если ПозицияПробела > 0 Тогда
    Результат = СокрЛП(Сред(СтрокаДанных, ПозицияПробела + 1));
КонецЕсли;

Если разделителем выступает конкретный фрагмент разметки (например, lang=EN-US>), мы можем сместить позицию на точную длину искомого вхождения:


Маркер = "lang=EN-US>";
ПозицияМаркера = СтрНайти(СтрокаДанных, Маркер);
Если ПозицияМаркера > 0 Тогда
    // Смещаем индекс на длину маркера и берем остаток строки
    Результат = СокрЛП(Сред(СтрокаДанных, ПозицияМаркера + СтрДлина(Маркер)));
КонецЕсли;

Способ 3. Разделение строки в массив (функция СтрРазделить)

Начиная с платформы 8.3.6, доступна встроенная функция СтрРазделить. С ее помощью можно разбить строку по заданному символу-разделителю без посимвольного перебора в цикле. Это делает код читаемым и производительным.

Разберем пример извлечения последней значимой части строки:


МассивЧастей = СтрРазделить(СтрокаДанных, ">", Ложь);
Если МассивЧастей.Количество() > 0 Тогда
    // Берем последний элемент после закрывающего символа
    ИндексПоследнего = МассивЧастей.Количество() - 1;
    Результат = СокрЛП(МассивЧастей[ИндексПоследнего]);
КонецЕсли;

Способ 4. Использование регулярных выражений (COM-объект VBScript.RegExp)

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

Посмотрим на программную реализацию поиска всех подходящих чисел:


RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;      // Поиск всех вхождений шаблона
RegExp.MultiLine = Истина;   // Многострочный режим
RegExp.Pattern = "\b[0-9]{6}\b"; // Поиск 6 цифр как отдельного слова

СтрокаПоиска = "2> 111222 3> 222333 4> 333444 5> 555666";
НайденныеСовпадения = RegExp.Execute(СтрокаПоиска);

Для Индекс = 0 По НайденныеСовпадения.Count - 1 Цикл
    ТекущееСовпадение = НайденныеСовпадения.Item(Индекс);
    Сообщить("Найдено значение: " + ТекущееСовпадение.Value);
КонецЦикла;

Важные особенности применения COM-объектов:

  1. Кроссплатформенность: Объект VBScript.RegExp работает исключительно в среде Windows. На сервере 1С под управлением Linux, в веб-клиенте или мобильном клиенте попытка создания COM-объекта вызовет исключение.
  2. Разрядность: На 64-разрядном сервере 1С вызовы 32-разрядных COM-библиотек требуют дополнительной настройки системных компонентов.

Способ 5. Потоковый разбор разметки через специализированные объекты

Если исходный файл содержит разметку вида lang=EN-US, это указывает на структуру HTML или XML. Ручной разбор таких файлов строковыми функциями часто дает сбои при малейшем изменении формата тегов или переносе строк.

Проанализируем специализированные объекты платформы 1С:

  1. Объекты ЧтениеHTML и ПостроительDOM: позволяют разобрать документ в объектную модель и обращаться к текстовому содержимому конкретных тегов напрямую, игнорируя префиксы и атрибуты.
  2. Объект ЧтениеXML: если документ является валидным XML, потоковое чтение узлов типа Текст защитит от ошибок некорректного экранирования.
  3. Чтение больших файлов: при разборе объемных текстовых файлов не следует считывать весь документ целиком в память через Прочитать(). Рекомендуется использовать построчный обход с помощью ЧтениеТекста.ПрочитатьСтроку(), что минимизирует нагрузку на оперативную память сервера.
← На главную