При обработке артикулов, номенклатурных номеров или кодов партий часто возникает задача отделить начальную буквенную часть строки от последующих цифр и спецсимволов. Например, имея строку вида "ГС230.150" или "ГС.230-150", требуется отсечь все числовые данные и сформировать новый код с заданным окончанием (к примеру, "ГС133"). При этом длина буквенного префикса может быть произвольной, а стандартные методы поиска подстроки по фиксированному разделителю (точке или тире) не подходят, если цифры идут сразу за буквами.
Разберем различные способы решения этой задачи на платформе 1С:Предприятие — от универсального посимвольного обхода до использования регулярных выражений.
Самый надежный, быстрый и универсальный способ для любых версий платформы 1С — это перебор строки по одному символу с помощью цикла. Проанализируем логику: перебираем позицию символа от 1 до длины строки, извлекаем текущий символ функцией Сред, проверяем, является ли он цифрой, и при первом же совпадении прерываем цикл.
Проверять символ на принадлежность к цифрам можно несколькими путями:
КодСимвола): цифры от 0 до 9 в кодировке Unicode/ASCII имеют коды от 48 до 57. Это наиболее производительный вариант, не требующий лишних операций со строками.Найти("0123456789", Символ).Посмотрим на практическую реализацию функции, которая извлекает начальный буквенный префикс с использованием кодов символов:
Функция ПолучитьПрефиксДоЦифры(ИсходнаяСтрока)
Длина = СтрДлина(ИсходнаяСтрока);
ПозицияПервойЦифры = 0;
Для Сч = 1 По Длина Цикл
ТекКод = КодСимвола(ИсходнаяСтрока, Сч);
// Коды символов '0'..'9' соответствуют диапазону 48..57
Если ТекКод >= 48 И ТекКод <= 57 Тогда
ПозицияПервойЦифры = Сч;
Прервать;
КонецЕсли;
КонецЦикла;
Если ПозицияПервойЦифры = 0 Тогда
// Цифры в строке не найдены — возвращаем всю строку
Возврат ИсходнаяСтрока;
ИначеЕсли ПозицияПервойЦифры = 1 Тогда
// Строка начинается сразу с цифры — буквенного префикса нет
Возврат "";
Иначе
// Возвращаем часть строки до первой найденной цифры
Возврат Лев(ИсходнаяСтрока, ПозицияПервойЦифры - 1);
КонецЕсли;
КонецФункции
Применим полученную функцию для формирования нового артикула:
ИсходныйКод = "ГС230.150";
БуквенныйПрефикс = ПолучитьПрефиксДоЦифры(ИсходныйКод); // Результат: "ГС"
НовыйКод = БуквенныйПрефикс + "133"; // Результат: "ГС133"
Если требуется написать более компактный код без запоминания кодов символов, можно использовать функцию Найти для сверки каждого символа со строкой-эталоном. Разберем этот пример:
Функция ВыделитьБуквеннуюЧасть(Знач ВходнойТекст)
Префикс = "";
ЭталонЦифр = "0123456789";
Для Индекс = 1 По СтрДлина(ВходнойТекст) Цикл
Символ = Сред(ВходнойТекст, Индекс, 1);
Если Найти(ЭталонЦифр, Символ) > 0 Тогда
// Наткнулись на первую цифру — останавливаем обработку
Прервать;
КонецЕсли;
// Очищаем префикс от возможных точек и разделителей, если это необходимо
Если Символ <> "." И Символ <> "-" Тогда
Префикс = Префикс + Символ;
КонецЕсли;
КонецЦикла;
Возврат Префикс;
КонецФункции
Начиная с версии 8.3.23, во встроенный язык платформы 1С добавлены штатные кроссплатформенные функции для работы с регулярными выражениями. Это позволяет решить задачу буквально в пару строк без явных циклов.
Рассмотрим использование функции СтрНайтиПоРегулярномуВыражению для поиска первой цифры (шаблон \d):
ИсходнаяСтрока = "ГС230.150";
РезультатПоиска = СтрНайтиПоРегулярномуВыражению(ИсходнаяСтрока, "\d");
Если РезультатПоиска <> Неопределено И РезультатПоиска.НачальнаяПозиция > 1 Тогда
БуквенныйПрефикс = Лев(ИсходнаяСтрока, РезультатПоиска.НачальнаяПозиция - 1);
ИначеЕсли РезультатПоиска <> Неопределено И РезультатПоиска.НачальнаяПозиция = 1 Тогда
БуквенныйПрефикс = "";
Иначе
БуквенныйПрефикс = ИсходнаяСтрока;
КонецЕсли;
НовыйКод = БуквенныйПрефикс + "133";
Также можно воспользоваться функцией СтрЗаменитьПоРегулярномуВыражению, чтобы сразу заменить хвост строки, начинающийся с цифры, на требуемое значение:
ИсходнаяСтрока = "ГС230.150";
// Заменяем первую цифру и все последующие символы до конца строки на "133"
НовыйКод = СтрЗаменитьПоРегулярномуВыражению(ИсходнаяСтрока, "\d.*$", "133");
// Результат: "ГС133"
На более старых версиях платформы для разбора строк часто применяли COM-объект VBScript.RegExp. Разберем пример его использования:
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Ложь;
RegExp.MultiLine = Ложь;
RegExp.Pattern = "^([^0-9]+)"; // Захватываем все символы до первой цифры
СтрокаВход = "ГС230.150";
Совпадения = RegExp.Execute(СтрокаВход);
Если Совпадения.Count > 0 Тогда
БуквенныйПрефикс = Совпадения.Item(0).Value;
Иначе
БуквенныйПрефикс = "";
КонецЕсли;
НовыйКод = БуквенныйПрефикс + "133";
Важно: COM-объекты работают исключительно в среде Windows. Если сервер 1С или клиентское рабочее место работает под управлением Linux, macOS или веб-клиента, данный код завершится критической ошибкой. Для кроссплатформенных решений рекомендуется использовать Способ 1 или встроенные регулярные выражения платформы 8.3.23+.
В процессе обсуждения часто предлагается разбить строку методом СтрРазделить(ИсходнаяСтрока, "0123456789"). Важно понимать особенность работы этой функции: параметр Разделитель воспринимается платформой как единая неделимая строка, а не как набор отдельных символов-разделителей. Метод будет искать точное вхождение подстроки "0123456789" целиком, поэтому разделить строку по каждой отдельной цифре таким образом не удастся.
Если разработка ведется в типовой конфигурации (например, ERP, УТ, КА, БП или УНФ), в составе конфигурации присутствует общий модуль СтроковыеФункцииКлиентСервер. В нем содержатся готовые оптимизированные функции для анализа строк, проверки символов и выделения подстрок, что позволяет не реализовывать низкоуровневые алгоритмы с нуля.