Как в 1С 7.7 извлечь адрес электронной почты из строки с ФИО?

Программист 1С v7.7
← На главную

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

Способ 1: Использование многострочной строки (метод подмены разделителя)

Рассмотрим самый простой и элегантный способ, предложенный участниками обсуждения. Его суть заключается в том, чтобы превратить обычную строку в список строк, где каждое слово будет находиться на новой строке. В 1С 7.7 это реализуется через замену пробелов на системную константу РазделительСтрок.

Проанализируем алгоритм:

  1. Заменяем все пробелы в исходной строке на символы переноса строки.
  2. Используем функцию СтрПолучитьСтроку(), чтобы забрать нужный фрагмент (в нашем случае — четвертый, если структура строго "Фамилия Имя Отчество Почта").

// Исходная строка
МояСтрока = "Иванов Иван Иванович ivan@mail.ru";

// Преобразуем пробелы в переносы строк
СтрокаСРазделителями = СтрЗаменить(МояСтрока, " ", РазделительСтрок);

// Извлекаем 4-й элемент (почту)
Почта = СтрПолучитьСтроку(СтрокаСРазделителями, 4);
Предупреждение("Найденная почта: " + Почта);

Важное замечание: Этот метод сработает идеально только в том случае, если между словами строго по одному пробелу. Если пользователь случайно нажал пробел дважды, метод "сдвинет" индексы. Чтобы этого избежать, перед обработкой рекомендуется "схлопнуть" лишние пробелы.


// Очистка от двойных пробелов
Пока Найти(МояСтрока, "  ") > 0 Цикл
    МояСтрока = СтрЗаменить(МояСтрока, "  ", " ");
КонецЦикла;

Способ 2: Поиск по уникальному маркеру (символ @)

Если структура ФИО нестабильна (например, нет отчества или фамилия двойная через пробел), полагаться на номер слова (4-е или 5-е) нельзя. В этом случае логичнее искать почту по её уникальному признаку — символу @. Разберем, как найти границы почтового адреса внутри текста.

Посмотрим на логику реализации:

  1. Находим позицию символа "собака".
  2. От этой позиции ищем ближайший пробел слева — это начало почты.
  3. Ищем ближайший пробел справа — это конец почты (или конец строки).

Функция ВырватьПочту(ВхСтр)
    ПозСобаки = Найти(ВхСтр, "@");
    Если ПозСобаки = 0 Тогда Возврат ""; КонецЕсли;
    
    // Ищем начало (пробел слева)
    Для к = 1 По ПозСобаки Цикл
        Символ = Сред(ВхСтр, ПозСобаки - к, 1);
        Если (Символ = " ") Или (ПозСобаки - к = 0) Тогда
            ПозНачала = ПозСобаки - к + 1;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    // Ищем конец (пробел справа)
    ОстатокСтроки = Сред(ВхСтр, ПозСобаки);
    ПозПробелаСправа = Найти(ОстатокСтроки, " ");
    Если ПозПробелаСправа = 0 Тогда
        ПозКонца = СтрДлина(ВхСтр);
    Иначе
        ПозКонца = ПозСобаки + ПозПробелаСправа - 2;
    КонецЕсли;
    
    Возврат Сред(ВхСтр, ПозНачала, ПозКонца - ПозНачала + 1);
КонецФункции

Способ 3: Использование регулярных выражений (RegExp)

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

Выясним, как это работает на практике:


// Создаем объект регулярных выражений
RegExp = СоздатьОбъект("VBScript.RegExp");
RegExp.IgnoreCase = 1; // Игнорировать регистр
RegExp.Global = 1;     // Искать все вхождения
RegExp.Pattern = "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"; // Шаблон почты

Matches = RegExp.Execute(ИсходнаяСтрока);
Если Matches.Count > 0 Тогда
    Результат = Matches.Item(0).Value;
    Сообщить("Найдена почта через RegExp: " + Результат);
КонецЕсли;

Преимущество этого метода в том, что нам совершенно неважно, сколько пробелов в строке, есть ли там цифры или другие символы. Регулярное выражение само найдет фрагмент, соответствующий стандарту написания email-адреса.

Способ 4: Инверсия поиска (с конца строки)

Зачастую в подобных выгрузках почта всегда является последним элементом строки. В 1С 7.7 нет встроенной функции поиска справа налево, но мы можем реализовать её самостоятельно. Проанализируем ситуацию: если мы найдем последний пробел в строке, то всё, что находится справа от него, и будет искомой почтой.

Рассмотрим пример функции:


Стр = СокрЛП(ИсходнаяСтрока);
Длина = СтрДлина(Стр);
Для НомерСимвола = 0 По Длина - 1 Цикл
    ТекСимвол = Сред(Стр, Длина - НомерСимвола, 1);
    Если ТекСимвол = " " Тогда
        Почта = Сред(Стр, Длина - НомерСимвола + 1);
        Прервать;
    КонецЕсли;
КонецЦикла;

Этот метод работает быстрее, чем создание COM-объектов, и надежнее, чем поиск по фиксированному индексу строки, так как количество слов в ФИО (два, три или четыре) перестает иметь значение.

Рекомендации по надежности

При выборе метода всегда учитывайте "грязность" ваших данных. Мы рекомендуем комбинировать подходы:

← На главную