В процессе разработки конфигураций и обработок в 1С регулярно возникает необходимость извлечь числовой параметр из текстовой строки. Типичный пример — текстовое наименование материала вида "Мат Стандарт 240-501", где первое число (240) обозначает ширину полотна, а второе — другой технологический параметр. Рассмотрим несколько способов решения этой задачи: от универсального алгоритмического перебора до современных встроенных средств платформы.
Разберем базовый алгоритм, который работает на любой платформе и не зависит от версии встроенного языка. Алгоритм заключается в последовательном проходе по всем символам строки, проверке каждого символа на принадлежность к цифрам и накоплении результата.
Посмотрим на пример реализации данного алгоритма, создающего список найденных в строке чисел:
ИсходнаяСтрока = "Мат Стандарт 240-501";
ЭталонЦифр = "0123456789";
ДлинаСтроки = СтрДлина(ИсходнаяСтрока);
СписокЧисел = Новый СписокЗначений;
ТекущаяЦифра = "";
Для Индекс = 1 По ДлинаСтроки Цикл
ТекущийСимвол = Сред(ИсходнаяСтрока, Индекс, 1);
Если Найти(ЭталонЦифр, ТекущийСимвол) > 0 Тогда
ТекущаяЦифра = ТекущаяЦифра + ТекущийСимвол;
Иначе
Если ТекущаяЦифра <> "" Тогда
СписокЧисел.Добавить(Число(ТекущаяЦифра));
ТекущаяЦифра = "";
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если ТекущаяЦифра <> "" Тогда
СписокЧисел.Добавить(Число(ТекущаяЦифра));
КонецЕсли;
// Первый элемент списка содержит число 240 (ширина)
Если СписокЧисел.Количество() > 0 Тогда
ШиринаПолотна = СписокЧисел[0].Значение;
КонецЕсли;
Проанализируем работу данного кода:
СтрДлина() вычисляет общее количество символов в наименовании.Сред() поочередно извлекается каждый символ.Найти() проверяет, входит ли символ в строку-шаблон "0123456789".Число и добавляется в массив или список значений.Если структура текстового поля заранее известна и постоянна (например, числовые параметры всегда разделены дефисом или пробелом), разберем более компактный метод с использованием функций СтрРазделить() и СтрНайти().
Рассмотрим ситуацию, когда ширина полотна находится перед дефисом. Посмотрим на следующий пример кода:
ИсходнаяСтрока = "Мат Стандарт 240-501";
// 1. Разбиваем строку по пробелам, чтобы получить последнюю часть с числами
МассивПодстрок = СтрРазделить(ИсходнаяСтрока, " ");
ПоследняяЧасть = МассивПодстрок[МассивПодстрок.ВГраница()]; // Получаем "240-501"
// 2. Находим позицию дефиса
ПозицияДефиса = СтрНайти(ПоследняяЧасть, "-");
Если ПозицияДефиса > 0 Тогда
ТекстШирины = Лев(ПоследняяЧасть, ПозицияДефиса - 1);
ШиринаПолотна = Число(ТекстШирины); // Получаем число 240
КонецЕсли;
Этот способ работает существенно быстрее посимвольного перебора, однако требует строгого соблюдения формата записи наименований.
Регулярные выражения — наиболее гибкий инструмент для поиска шаблонов в тексте. Способ реализации зависит от используемой версии платформы 1С:Предприятие.
Вариант А: Встроенные функции (Платформа 8.3.23 и новее)
Начиная с версии 8.3.23, в платформу добавлены штатные функции работы с регулярными выражениями. Выясним, как извлечь первое числовое значение из строки с их помощью:
ИсходнаяСтрока = "Мат Стандарт 240-501";
Шаблонпоиска = "\d+"; // Ищем одну или несколько цифр подряд
РезультатПоиска = СтрНайтиПоРегулярномуВыражению(ИсходнаяСтрока, Шаблонпоиска);
Если РезультатПоиска <> Неопределено Тогда
ИзвлеченныйТекст = Сред(ИсходнаяСтрока, РезультатПоиска.НачальнаяПозиция, РезультатПоиска.Длина);
ШиринаПолотна = Число(ИзвлеченныйТекст); // Получаем 240
КонецЕсли;
Вариант Б: COM-объект VBScript.RegExp (Для старых версий платформы)
В более ранних версиях платформы регулярные выражения применяются через COM-объект VBScript.RegExp:
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Ложь; // Берем только первое совпадение
RegExp.Pattern = "\d+";
Совпадения = RegExp.Execute("Мат Стандарт 240-501");
Если Совпадения.Count > 0 Тогда
ШиринаПолотна = Число(Совпадения.Item(0).Value);
КонецЕсли;
Важное ограничение: Использование COMОбъект("VBScript.RegExp") работает исключительно под управлением ОС Windows. На серверах под Linux данный метод вызовет ошибку выполнения.
Парсинг текстовых строк — это всегда потенциальный источник ошибок при изменении формата наименования (например, при внесении опечаток или добавлении артикула). В качестве наилучшей практики рекомендуется:
Ширина с типом Число) или использовать механизм дополнительных реквизитов и сведений БСП.