В процессе разработки в среде 1С:Предприятие часто возникает задача извлечения специфических данных из неструктурированных строк. Это может быть код торговой точки, номер инцидента, артикул или ISBN книги. Рассмотрим подробнее различные подходы к решению этой задачи на примере извлечения четырехзначного кода из строки с контактной информацией и адресом.
Один из наиболее гибких способов парсинга текста — это использование регулярных выражений (Regular Expressions). В операционных системах Windows это реализуется через VBScript.RegExp. Разберем по шагам, как настроить поиск четырех цифр, идущих подряд.
Для начала создадим объект и настроим шаблон поиска. Проанализируем ситуацию: если нам нужно найти ровно 4 цифры (код точки), шаблон будет \d{4}.
// Пример использования регулярных выражений
Процедура ИзвлечьКодРегуляркой(ИсходнаяСтрока)
Попытка
RegExp = Новый COMОбъект("VBScript.RegExp");
Исключение
Сообщить("Не удалось создать объект VBScript.RegExp. Проверьте настройки ОС.");
Возврат;
КонецПопытки;
RegExp.IgnoreCase = Истина; // Игнорировать регистр
RegExp.Global = Истина; // Искать все вхождения
RegExp.MultiLine = Ложь; // Однострочный режим
// Устанавливаем шаблон: ищем 4 цифры (\d{4})
RegExp.Pattern = "(\d{4})";
Matches = RegExp.Execute(ИсходнаяСтрока);
Если Matches.Count > 0 Тогда
// Берем первое найденное совпадение
Результат = Matches.Item(0).Value;
Сообщить("Найденный код: " + Результат);
КонецЕсли;
КонецПроцедуры
Важный нюанс: обычный поиск четырех цифр может вернуть год или часть номера телефона. Чтобы повысить точность, можно использовать привязку к контексту, например, искать цифры, которые находятся только внутри скобок: \(\d{4}\).
Если вы работаете на современной платформе (начиная с версии 8.3.24), использование COM-объектов уходит в прошлое. Теперь в 1С реализована родная поддержка Regex. Это работает быстрее и, что критично, кроссплатформенно (поддерживается на Linux-серверах).
Рассмотрим пример кода с использованием нового класса РезультатПоискаRegex. Попробуем извлечь код, который начинается с префикса "ЦМС":
// Использование встроенного в платформу Regex
Функция ПолучитьКодЦМС(Текст)
// Шаблон: ^ЦМС (начало строки, слово ЦМС и пробел), далее любые цифры
Шаблон = "^ЦМС \d+";
// Создаем объект Regex
ОбъектRegex = Новый Regex(Шаблон);
Результат = ОбъектRegex.Найти(Текст);
Если Результат <> Неопределено Тогда
Возврат Результат.Значение;
КонецЕсли;
Возврат "";
КонецФункции
Бывают ситуации, когда использование регулярных выражений кажется избыточным или требуется решение "здесь и сейчас" без обращения к внешним объектам. Выясним причину популярности метода манипуляции строками: он прост в отладке.
Рассмотрим вариант, когда мы заранее знаем, что искомый код находится перед фразой "График работы:". Мы можем заменить эту фразу на символ переноса строки и получить нужную часть текста.
// Извлечение через манипуляцию подстроками
ИзначальнаяСтрока = "Адрес офиса: Бугуруслан, ул.Революционная, 35 (6414) График работы: Пн-Вс: (08:00-20:00)";
// Шаг 1: Отрезаем всё, что после "График работы"
НоваяСтрока = СтрЗаменить(ИзначальнаяСтрока, "График работы:", Символы.ПС);
ВременнаяПеременная = СтрПолучитьСтроку(НоваяСтрока, 1);
// Шаг 2: Берем последние символы перед разрывом (учитывая пробелы и скобки)
// Код (6414) занимает 6 символов вместе со скобками
КодТочки = Лев(Прав(СокрЛП(ВременнаяПеременная), 5), 4);
Сообщить("Код точки: " + КодТочки);
Если структура строки крайне нестабильна (код может быть в скобках, а может и нет), проанализируем ситуацию с помощью обхода массива слов. Разделим строку по пробелам и проверим каждое слово на соответствие нашим критериям (например, длина ровно 4 символа и это число).
Функция ИзвлечьКодИзМассива(ИсходнаяСтрока)
// Очищаем строку от скобок для упрощения
ОчищеннаяСтрока = СтрЗаменить(СтрЗаменить(ИсходнаяСтрока, "(", " "), ")", " ");
// Разбиваем строку на массив слов
МассивСлов = СтрРазделить(ОчищеннаяСтрока, " ", Ложь);
Для Каждого Слово Из МассивСлов Цикл
Слово = СокрЛП(Слово);
// Проверяем: длина 4 и состоит только из цифр
Если СтрДлина(Слово) = 4 И СтрНайти("0123456789", Лев(Слово, 1)) > 0 Тогда
// Дополнительная проверка, что это действительно число
Попытка
ЧисловойКод = Число(Слово);
Возврат Слово;
Исключение
Продолжить;
КонецПопытки;
КонецЕсли;
КонецЦикла;
Возврат "";
КонецФункции
При работе с регулярными выражениями крайне важно правильно составить шаблон. Разберем наиболее частые примеры, встречающиеся в практике 1С-разработчика:
(?=[-0-9X ]{17}|[-0-9X ]{13}|[0-9X]{10})(?:97[89][- ]?)?[0-9]{1,5}[- ]?(?:[0-9]+[- ]?){2}[0-9X] — сложный шаблон для поиска международного номера книги.\d{4}-\D{3} (например, 0451-НВС). Здесь \D означает любой символ, не являющийся цифрой.^ЦМС \d+. Символ ^ жестко привязывает поиск к началу строки.При загрузке данных из внешних источников, таких как Excel, следует учитывать несколько критических моментов:
Во-первых, перед началом парсинга всегда выполняйте нормализацию строки. В Excel часто встречаются неразрывные пробелы (код символа 160), которые обычная функция СокрЛП не удаляет. Рекомендуется заменить их на обычные пробелы:
СтрЗаменить(ИсходнаяСтрока, Символы.НПП, " ");
Во-вторых, если задача парсинга адресов становится регулярной и масштабной, рассмотрите использование специализированных API (например, DaData). Это позволит не только извлечь код, но и привести весь адрес к федеральному стандарту (ФИАС/ГАР), выделив город, улицу и дом в отдельные поля структуры.
В-третьих, всегда обрабатывайте исключения при создании COM-объектов. Если ваш код будет выполняться на сервере под управлением Linux, VBScript.RegExp не инициализируется, и программа выдаст ошибку. В таких случаях используйте либо стандартные строковые функции 1С, либо (для версий 8.3.24+) новые встроенные механизмы Regex.
Подводя итог, выбор метода зависит от версии вашей платформы и сложности входных данных. Регулярные выражения предоставляют наибольшую мощь, в то время как стандартные функции 1С гарантируют простоту поддержки кода коллегами.