Как преобразовать строку с разделителями типа "12.34.56.78" в массив чисел в 1С?

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

В процессе разработки в среде 1С:Предприятие часто возникает задача разбора текстовых строк, содержащих числовые данные, разделенные определенными знаками препинания. Ярким примером является обработка IP-адресов, версий программного обеспечения (например, "8.3.23.15), артикулов со сложной структурой или штрихкодов. Нам необходимо не просто разбить исходную строку на подстроки, но и преобразовать их в полноценный числовой тип для последующих математических операций или корректной сортировки.

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

Способ 1. Классический разбор с помощью функции СтрРазделить() и безопасного приведения типов

Этот способ является наиболее универсальным и работает практически на любых версиях платформы 1С:Предприятие 8. Основная идея заключается в использовании встроенной функции СтрРазделить, которая разбивает исходный текст по указанному маркеру (в нашем случае это точка) и возвращает массив строк. После этого мы должны обойти полученные элементы в цикле и преобразовать их в числа.

Однако простое преобразование через функцию Число() таит в себе опасность: если во входящих данных случайно окажется опечатка или буква (например, "12.34a.56.78"), программа завершит работу аварийно. Чтобы избежать этого, мы применим конструкцию Попытка — Исключение для безопасного приведения типов.

Рассмотрим пример готовой функции:


Функция ВыделитьЧислаИзСтроки(Знач ИсходнаяСтрока) Экспорт
    
    Результат = Новый Массив;
    
    // Разбиваем строку на подстроки, используя в качестве разделителя точку
    МассивПодстрок = СтрРазделить(ИсходнаяСтрока, ".");
    
    // Обходим полученный массив строк в цикле
    Для Каждого ТекущаяПодстрока Из МассивПодстрок Цикл
        
        // Очищаем строку от случайных пробелов по краям
        ОчищеннаяСтрока = СокрЛП(ТекущаяПодстрока);
        
        // Используем защищенный блок для преобразования типов
        Попытка
            ЧисловоеЗначение = Число(ОчищеннаяСтрока);
            Результат.Добавить(ЧисловоеЗначение);
        Исключение
            // Если преобразовать строку в число не удалось, 
            // записываем дефолтное значение 0 или обрабатываем ошибку иначе
            Результат.Добавить(0);
        КонецПопытки;
        
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции

Преимущества метода: простота реализации, отсутствие внешних зависимостей, высокая скорость работы на небольших объемах данных.

Недостатки: жесткая привязка к одному конкретному разделителю. Если формат строки изменится (например, вместо точек появятся дефисы), код придется переписывать.

Способ 2. Использование встроенных регулярных выражений (для платформы 8.3.23 и выше)

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

Для решения нашей задачи мы применим метод СтрНайтиВсеПоРегулярномуВыражению() с шаблоном "\d+", который означает поиск одной или более цифр подряд.

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


Функция ВыделитьЧислаРегулярнымВыражением(Знач ИсходнаяСтрока) Экспорт
    
    Результат = Новый Массив;
    ШаблонПоиска = "\d+"; // Регулярное выражение для поиска целых чисел
    
    // Получаем коллекцию совпадений
    НайденныеСовпадения = СтрНайтиВсеПоРегулярномуВыражению(ИсходнаяСтрока, ШаблонПоиска);
    
    // Обходим результаты поиска
    Для Каждого Соответствие Из НайденныеСовпадения Цикл
        
        // Извлекаем подстроку, используя начальную позицию и длину найденного фрагмента
        ПодстрокаЧисла = Сред(ИсходнаяСтрока, Соответствие.НачальнаяПозиция, Соответствие.Длина);
        
        // Добавляем преобразованное значение в результирующий массив
        Результат.Добавить(Число(ПодстрокаЧисла));
        
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции

Преимущества метода: невероятная гибкость. Данный код без проблем обработает строки вида "12...34---56///78" или даже текстовые строки вроде "Номер12, подномер34, индекс56". Нам больше не нужно беспокоиться о символах-разделителях.

Недостатки: метод доступен только на современных версиях платформы (8.3.23+).

Способ 3. Профессиональная разработка с использованием функций БСП

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

Мы задействуем функции общего модуля СтроковыеФункцииКлиентСервер:

  1. РазложитьСтрокуВМассивПодстрок() — мощный аналог стандартной функции разделения строк, который умеет автоматически обрезать пробельные символы и игнорировать пустые элементы.
  2. СтрокаВЧисло() — функция безопасного приведения типов, которая никогда не вызывает критических ошибок и возвращает 0 при невозможности конвертации.

Посмотрим на пример интеграции БСП в наш алгоритм:


Функция ПолучитьЧислаСИспользованиемБСП(Знач ИсходнаяСтрока) Экспорт
    
    Результат = Новый Массив;
    
    // Разбираем строку на подстроки. Третий параметр "Истина" автоматически удалит лишние пробелы.
    МассивПодстрок = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(ИсходнаяСтрока, ".", Истина);
    
    Для Каждого Подстрока Из МассивПодстрок Цикл
        
        // Безопасно преобразуем подстроку в число без использования конструкции Попытка-Исключение
        ЧисловоеЗначение = СтроковыеФункцииКлиентСервер.СтрокаВЧисло(Подстрока);
        
        Результат.Добавить(ЧисловоеЗначение);
        
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции

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

Недостатки: требует наличия БСП в конфигурации (не подходит для самописных конфигураций "с нуля").

Способ 4. Посимвольный обход строки (низкоуровневый ручной разбор)

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

Для определения того, является ли текущий символ цифрой, мы будем проверять его ASCII-код. Нам известно, что цифровые символы от "0" до "9" занимают в таблице кодов диапазон от 48 до 57 включительно.

Разберем данный алгоритм по шагам:


Функция ВыделитьЧислаПосимвольно(Знач ИсходнаяСтрока) Экспорт
    
    Результат = Новый Массив;
    НакопленнаяСтрокаЦифр = "";
    
    КоличествоСимволов = СтрДлина(ИсходнаяСтрока);
    
    Для Индекс = 1 По КоличествоСимволов Цикл
        
        ТекущийСимвол = Сред(ИсходнаяСтрока, Индекс, 1);
        КодСимвола = КодСимвола(ТекущийСимвол);
        
        // Проверяем, входит ли символ в числовой диапазон ASCII (48 - 57)
        Если КодСимвола >= 48 И КодСимвола <= 57 Тогда
            // Если это цифра, добавляем её к нашему временному буферу
            НакопленнаяСтрокаЦифр = НакопленнаяСтрокаЦифр + ТекущийСимвол;
        Иначе
            // Если встретился разделитель, и в буфере накоплены цифры — преобразуем в число
            Если НЕ ПустаяСтрока(НакопленнаяСтрокаЦифр) Тогда
                Результат.Добавить(Число(НакопленнаяСтрокаЦифр));
                НакопленнаяСтрокаЦифр = ""; // Очищаем буфер для следующего числа
            КонецЕсли;
        КонецЕсли;
        
    КонецЦикла;
    
    // Проверяем буфер после завершения цикла (для чисел в самом конце строки)
    Если НЕ ПустаяСтрока(НакопленнаяСтрокаЦифр) Тогда
        Результат.Добавить(Число(НакопленнаяСтрокаЦифр));
    КонецЕсли;
    
    Возврат Результат;
    
КонецФункции

Преимущества метода: работает абсолютно на любой платформе 1С (включая старые версии 7.7 и 8.0/8.1/8.2), не зависит от используемых разделителей.

Недостатки: больший объем кода, потенциально более низкая скорость выполнения на экстремально длинных строках по сравнению со встроенными компилируемыми методами платформы.

Резюме и рекомендации

Мы проанализировали четыре принципиально разных подхода к выделению чисел из форматированной строки. Какой же метод выбрать для практического применения?

← На главную