Как извлечь адрес электронной почты (e-mail) из текста в 1С?

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

При работе со строковыми данными в 1С часто возникает задача поиска и извлечения адресной информации, такой как e-mail. Простой поиск символа @ с помощью функции СтрНайти не всегда удобен, так как адрес может быть окружен знаками препинания или располагаться внутри сложного текста. Рассмотрим подробнее несколько способов решения этой задачи: использование встроенных средств платформы 1С, работу через COM-объект VBScript.RegExp и алгоритм строкового парсинга.

Способ 1. Использование встроенных функций регулярных выражений (Платформа 8.3.23 и выше)

Начиная с версии платформы 8.3.23, в 1С добавлена встроенная кроссплатформенная поддержка регулярных выражений стандарта ICU. Это наиболее универсальный и безопасный способ, поскольку он работает на любых операционных системах (включая Linux), а также в веб-клиенте без вызова внешних библиотек.

Для поиска всех вхождений e-mail в тексте воспользуемся функцией СтрНайтиВсеПоРегулярномуВыражению. Проанализируем пример кода:


Шаблон = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}";
ТекстИсточника = "Свяжитесь с нами по адресу vasya@mail.ru или support@company.com для уточнения деталей.";

МассивРезультатов = СтрНайтиВсеПоРегулярномуВыражению(ТекстИсточника, Шаблон);

Для Каждого Результат Из МассивРезультатов Цикл
    НайденныйEmail = Сред(ТекстИсточника, Результат.НачальнаяПозиция, Результат.Длина);
    Сообщить("Найден адрес: " + НайденныйEmail);
КонецЦикла;

Если необходимо обработать кириллические доменные имена (например, адреса в зоне .рф), расширим диапазон символов в шаблоне:

Шаблон = "[a-zA-Zа-яА-Я0-9._%+-]+@[a-zA-Zа-яА-Я0-9.-]+\.[a-zA-Zа-яА-Я]{2,}";

Способ 2. Использование COM-объекта VBScript.RegExp (для ОС Windows)

В более ранних версиях платформы (до 8.3.23) штатного механизма регулярных выражений не было. В среде Windows для этого традиционно применяется объект VBScript.RegExp.

Важное ограничение: данный подход работает только под управлением ОС Windows. В тонком клиенте на Linux или в веб-клиенте вызов COMОбъект приведет к ошибке, поэтому обработку через COM необходимо выполнять на стороне сервера под Windows.

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


RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина; // Игнорировать регистр
RegExp.Global = Истина;     // Поиск всех вхождений шаблона
RegExp.MultiLine = Ложь;    // Многострочный режим
RegExp.Pattern = "([+0-9A-Za-z._-]+)@([A-Za-z0-9.-]+\.[A-Za-z]{2,})";

СтрВход = "Контактный адрес: vasya@mail.ru";
МассивСовпадений = RegExp.Execute(СтрВход);

Если МассивСовпадений.Count() > 0 Тогда
    // Получаем первое найденное совпадение
    Совпадение = МассивСовпадений.Item(0);
    
    // Извлекаем подстроки, захваченные скобками в регулярном выражении
    Подмаски = Совпадение.SubMatches;
    ДоСобаки = Подмаски.Item(0);
    ПослеСобаки = Подмаски.Item(1);
    
    ПолныйАдрес = Совпадение.Value;
    
    Сообщить("Логин: " + ДоСобаки);
    Сообщить("Домен: " + ПослеСобаки);
    Сообщить("Полный e-mail: " + ПолныйАдрес);
КонецЕсли;

Обратите внимание на составление регулярного выражения: не рекомендуется использовать конструкции вида [A-z], так как в таблице ASCII между заглавными и строчными латинскими буквами расположены специальные символы (квадратные скобки, символ подчеркивания и др.), что может привести к некорректным срабатываниям. Безопаснее явно указывать [a-zA-Z] или задавать свойство RegExp.IgnoreCase = Истина.

Способ 3. Извлечение адреса алгоритмическим путем (без регулярных выражений)

Если решение должно работать на версиях платформы ниже 8.3.23 в Linux или веб-клиенте без вызова внешних библиотек, поиск можно реализовать встроенными функциями работы со строками.

Рассмотрим алгоритм действий:

  1. С помощью СтрНайти находим позицию символа @ в тексте.
  2. Двигаемся от символа @ влево, пока не встретим недопустимый символ (пробел, кавычка, запятая, символ переноса строки) — это сформирует имя ящика.
  3. Двигаемся от символа @ вправо до первого недопустимого разделителя — это сформирует доменную часть.
  4. Объединяем полученные подстроки и проверяем наличие точки в доменной части.

Рефакторинг кода: замена конструкций по шаблону

В рамках темы также обсуждался вопрос массовой замены конструкций вызова справочников в коде модулей (например, замена Справочники.КлассификаторЕдиницИзмерения.НайтиПоКоду("168") на _ПовтИсп.ПолучитьЭлементПоКоду("КлассификаторЕдиницИзмерения", "168")).

В версии 8.3.23 и выше данная задача рефлексии и рефакторинга решается функцией СтрЗаменитьПоРегулярномуВыражению с использованием ссылок на захваченные группы ($1 и $2):


ИсходныйТекст = "Объект = Справочники.КлассификаторЕдиницИзмерения.НайтиПоКоду(""168"");";
ШаблонЗамены = "Справочники\.([A-Za-z0-9_]+)\.НайтиПоКоду\(([^)]+)\)";
СтрокаЗамены = "_ПовтИсп.ПолучитьЭлементПоКоду(""$1"", $2)";

Результат = СтрЗаменитьПоРегулярномуВыражению(ИсходныйТекст, ШаблонЗамены, СтрокаЗамены);

Для более ранних версий платформы аналогичный рефакторинг модулей выполняется штатными инструментами Конфигуратора через диалог «Глобальный поиск и замена».

← На главную