Как с помощью регулярных выражений извлечь ФИО и телефон из текста письма в 1С?

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

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

Метод 1: Использование COM-объекта VBScript.RegExp (для версий ниже 8.3.24)

Долгое время основным способом работы с регулярными выражениями в среде 1С было использование внешнего объекта VBScript.RegExp. Этот метод до сих пор актуален для систем, работающих под управлением Windows. Разберем по шагам, как настроить этот объект и извлечь нужные данные.

Для начала проанализируем инициализацию объекта и его ключевые свойства:


RegExp = Новый COMОбъект("VBScript.RegExp"); 
RegExp.IgnoreCase = Истина; // Игнорировать регистр (А=а)
RegExp.Global = Истина;     // Поиск всех вхождений, а не только первого
RegExp.MultiLine = Истина;  // Текст рассматривается как многострочный

Когда мы ищем конкретные данные, такие как имя клиента, нам важно не просто найти слово "Имя", но и захватить текст, который идет следом за ним. Для этого используются захватывающие группы (круглые скобки в шаблоне). Посмотрим на пример кода, который извлекает имя, находящееся между маркером "Имя:" и каким-либо завершающим символом (например, тегом или переносом строки):


// Шаблон ищет текст после слова "Имя:" до ближайшего символа "<"
RegExp.Pattern = "Имя: (.*?)<"; 
Matches = RegExp.Execute(СодержаниеПисьма);

Если Matches.Count > 0 Тогда
    // Получаем первое совпадение
    Match = Matches.Item(0);
    // Извлекаем только то, что попало в скобки (SubMatches)
    ФИО = Match.SubMatches.Item(0);
    Сообщить("Найден клиент: " + ФИО);
КонецЕсли;

Важный нюанс: использование Match.SubMatches.Item(0) позволяет отсечь сам маркер "Имя:" и получить только полезную нагрузку. Если использовать просто Match.Value, вы получите всю строку целиком, включая поисковый запрос.

Метод 2: Встроенные регулярные выражения (Платформа 8.3.24+)

Проанализируем современные возможности платформы. Начиная с версии 8.3.24, в 1С появилась родная поддержка регулярных выражений. Это критически важно для систем, работающих на Linux, так как COM-объекты там недоступны. Кроме того, встроенные механизмы работают быстрее.

Рассмотрим, как будет выглядеть поиск телефона и имени с использованием новых объектов РегулярноеВыражение и РезультатПоискаРегулярногоВыражения:


// Создаем объект регулярного выражения
// Паттерн для поиска телефона в форматах +7... или 8...
ПаттернТелефон = "((\+7|8)[\s\-]?\(?\d{3}\)?[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2})";
РегВыр = Новый РегулярноеВыражение(ПаттернТелефон);

// Ищем совпадения в тексте
Результат = РегВыр.Найти(ТекстПисьма);

Для Каждого Совпадение Из Результат Цикл
    Телефон = Совпадение.Значение;
    Сообщить("Найден номер: " + Телефон);
КонецЦикла;

Встроенные выражения поддерживают стандарт PCRE, что дает программисту гораздо больше гибкости в управлении поиском.

Особенности составления шаблонов: Жадность и Ленивость

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

Чтобы ограничить поиск, используем ленивый квантификатор .*?. Рассмотрим разницу:

Проанализируем пример для сложной структуры со звездочками, как в исходном вопросе:


// Ищем текст между "Имя" и следующим блоком данных "Телефон"
// Учитываем возможные переносы строк (\n) и служебные символы (\*)
RegExp.Pattern = "Имя\*+([\s\S]*?)Телефон";

Подготовка текста перед поиском

Часто регулярное выражение не срабатывает из-за невидимых символов. Письма в формате HTML могут содержать неразрывные пробелы ( ) или специфические кодировки. Перед запуском поиска крайне рекомендуется выполнить предварительную очистку текста.

Выясним причины возможных неудач и устраним их:

  1. Неразрывные пробелы: Замените символ Символы.НПП на обычный пробел.
  2. HTML-теги: Если письмо пришло в формате HTML, а вы ищете текст, регулярное выражение может наткнуться на теги внутри слов. Используйте методы очистки текста от HTML-разметки.
  3. Кодировка: Убедитесь, что текст письма корректно прочитан в кодировку UTF-8. Если 1С работает с Win-1251, а письмо в UTF-8, кириллические шаблоны (например, "Имя") не сработают.

Пример предварительной обработки:


ТекстДляПоиска = СтрЗаменить(Содержание.Текст, Символы.НПП, " ");
ТекстДляПоиска = СтрЗаменить(ТекстДляПоиска, Символы.Таб, " ");
// Теперь можно применять RegExp.Execute(ТекстДляПоиска)

Универсальные шаблоны для ФИО и Телефона

Вместо того чтобы полагаться на жесткую структуру письма (количество звездочек или пробелов), лучше использовать более универсальные паттерны, которые ищут сами данные, а не их окружение.

Для поиска ФИО (Кириллица):
Шаблон ([А-ЯЁ][а-яё]+\s+[А-ЯЁ][а-яё]+(?:\s+[А-ЯЁ][а-яё]+)?) ищет слова, начинающиеся с заглавной буквы. Это позволит найти "Иван Иванович Иванов" даже если структура письма изменится.

Для поиска Телефона:
Шаблон ((\+7|8)[\s\-]?\(?\d{3}\)?[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2}) учитывает наличие скобок, тире и пробелов в номере телефона. Это гораздо надежнее, чем искать "все символы после слова Телефон".

Таким образом, комбинируя методы очистки текста, ленивые квантификаторы и группы захвата SubMatches, мы создаем отказоустойчивый механизм обработки почтовых сообщений в 1С.

← На главную