В процессе разработки в среде 1С:Предприятие часто возникает задача парсинга строк, полученных из внешних систем или текстовых файлов. Типичный пример — строка номенклатуры, где в самом конце указана цена или артикул, отделенные пробелом. В этой статье мы подробно разберем, как эффективно извлечь символы справа до первого встретившегося пробела, рассмотрим несколько программных подходов и обсудим важные нюансы, такие как неразрывные пробелы и работа на разных версиях платформы. Для автоматизации регулярного получения таких внешних файлов по электронной почте, FTP или HTTP удобно настроить сбор прайс-листов с почты, FTP, HTTP, их обработку и выгрузку.
Этот способ считается наиболее читаемым и современным. Суть метода заключается в том, чтобы разбить исходную строку на массив подстрок, используя пробел в качестве разделителя, а затем просто взять последний элемент этого массива.
Рассмотрим пример кода:
ИсходнаяСтрока = "23452 Карандаш зеленый кол-во 340";
МассивЧастей = СтрРазделить(ИсходнаяСтрока, " ", Ложь);
Если МассивЧастей.Количество() > 0 Тогда
Цена = МассивЧастей[МассивЧастей.ВГраница()];
Сообщить(Цена); // Выведет "340"
КонецЕсли;
Проанализируем ситуацию: обратите внимание на третий параметр функции СтрРазделить. Передавая значение Ложь, мы указываем системе, что пустые строки в массив включать не нужно. Это крайне важно, если в конце вашей строки случайно окажется лишний пробел (например, "Цена 340 "). Без этого параметра последним элементом массива была бы пустая строка.
Этот метод более производителен, так как не создает временный объект массива. Мы используем функцию СтрНайти с указанием направления поиска. Разберем по шагам, как это реализовать:
Посмотрим на пример реализации:
Текст = "23452 Карандаш зеленый кол-во 340";
ПозицияПробела = СтрНайти(Текст, " ", НаправлениеПоиска.СКонца);
Если ПозицияПробела > 0 Тогда
Результат = Сред(Текст, ПозицияПробела + 1);
Иначе
Результат = Текст; // Пробелов нет, берем всю строку
КонецЕсли;
Здесь функция Сред при указании только двух параметров автоматически берет все символы до конца строки, что избавляет нас от необходимости вычислять её длину через СтрДлина.
Если вы предпочитаете использовать функцию Прав, алгоритм немного усложняется, так как нам нужно точно знать количество символов, которые мы хотим забрать справа. Выясним причину популярности этого метода: он часто встречается в старом коде и учебниках.
Стр = "23452 Карандаш зеленый кол-во 340";
Позиция = СтрНайти(Стр, " ", НаправлениеПоиска.СКонца);
Если Позиция > 0 Тогда
КоличествоСимволов = СтрДлина(Стр) - Позиция;
Цена = Прав(Стр, КоличествоСимволов);
КонецЕсли;
Начиная с версии платформы 8.3.24, в 1С появилась нативная поддержка регулярных выражений. Теперь задачу можно решить максимально изящно и кроссплатформенно (код будет работать и на Linux-серверах без лишних манипуляций). Для работы с регулярными выражениями на более ранних версиях платформы можно использовать подсистему для работы с регулярными выражениями.
Рассмотрим подробнее использование нового объекта РегулярноеВыражение:
Текст = "23452 Карандаш зеленый кол-во 340";
РегВыр = Новый РегулярноеВыражение("(\S+)$"); // Ищем группу непробельных символов в конце строки
РезультатПоиска = РегВыр.Найти(Текст);
Если РезультатПоиска <> Неопределено Тогда
Цена = РезультатПоиска.Группы[0].Значение;
КонецЕсли;
Этот метод хорош тем, что он автоматически игнорирует любые пробельные символы в конце, если правильно составить паттерн.
При работе со строками в 1С важно учитывать несколько критических моментов, которые могут привести к ошибкам в расчетах:
1. Проблема неразрывных пробелов. Часто данные, скопированные из Excel или веб-страниц, содержат так называемый "неразрывный пробел" (код символа 160 или Символы.НПП). Обычная функция СтрНайти(Текст, " ") его не увидит. Перед обработкой рекомендуется выполнить замену:
ОбработаннаяСтрока = СтрЗаменить(ИсходнаяСтрока, Символы.НПП, " ");
2. Преобразование в число. После того как вы получили подстроку "340", её нужно преобразовать для математических операций. Используйте функцию Число(), но предварительно очистите строку функцией СокрЛП, чтобы избежать ошибок из-за невидимых символов.
3. Работа в запросах. Помните, что внутри языка запросов 1С функционал работы со строками крайне ограничен. Там нет возможности искать символ с конца или разбивать строку в массив. Если вам нужно получить цену из строки в запросе, старайтесь либо заранее хранить её в отдельном реквизите, либо обрабатывать результат запроса уже в коде на языке 1С.
Подведем итог: для большинства повседневных задач оптимальным выбором будет Метод 1 (СтрРазделить) из-за его простоты и читаемости. Если же критична производительность (например, при обработке сотен тысяч строк в цикле), лучше использовать Метод 2 (СтрНайти с конца).