При вводе контактной информации контрагентов пользователи часто совершают случайные ошибки: забывают ввести символ «@», ставят точку в самом конце адреса, допускают опечатки в доменной части или случайно добавляют лишние пробелы. Для борьбы с этой проблемой разработчики часто прибегают к валидации данных. Давайте подробно разберем, как решить задачу ограничения «косорукости» ввода e-mail в 1С, проанализируем популярные регулярные выражения из обсуждения на форуме, выявим их скрытые угрозы и рассмотрим наиболее современные и надежные инструменты платформы.
На форумах часто предлагают использовать собственные регулярные выражения. Рассмотрим шаблон, к которому пришел автор темы в процессе обсуждения:
^[^а-я]+@[^а-я]+\.[^а-я\._'+;*^&=?~{}\-\.\/,\\]+$
Проанализируем этот шаблон по шагам, чтобы понять его логику и выявить слабые стороны:
[^а-я] пытается запретить ввод русских букв в адресе почты.@ жестко зафиксирован в середине выражения.\. проверяет, что после «собаки» есть точка, разделяющая домен.[^а-я\._'+;*^&=?~{}\-\.\/,\\]+ запрещает завершать почтовый адрес точкой, слэшем, подчеркиванием или другими служебными знаками.Несмотря на то, что данный шаблон решает локальную задачу автора (запретить пробелы, двойные точки и точки на конце), он обладает рядом критических недостатков, которые могут привести к потере реальных клиентов компании.
Использование конструкции [^а-я] для полной блокировки кириллицы в современных реалиях бизнеса — это грубая ошибка. Согласно международным стандартам IDN (Internationalized Domain Names) и EAI (Email Address Internationalization, стандарты RFC 6530 и более новые), почтовые ящики и домены на национальных алфавитах официально существуют и активно используются.
Адреса вида иван@почта.рф или отдел-продаж@компания.бел абсолютно валидны. Если применить шаблон автора темы на «боевой» базе, менеджеры физически не смогут ввести контакты клиентов, использующих русскоязычные домены. Система выдаст ошибку, и компания потеряет потенциальные лиды.
Составление сложных «самописных» регулярных выражений с избыточным использованием вложенных квантификаторов (например, знаков * или + внутри других групп, как показано в сообщении №13 форума) несет в себе скрытую угрозу безопасности системы.
При попытке проверить специально подготовленную некорректную строку длинный шаблон может вызвать так называемый катастрофический возврат (catastrophic backtracking). В этот момент движок регулярных выражений начнет перебирать миллионы комбинаций символов, зависнет и загрузит процессор сервера 1С на 100%. Это приведет к отказу в обслуживании (ReDoS-атаке) и парализует работу всех остальных пользователей базы.
Написать регулярное выражение, на 100% соответствующее официальному стандарту RFC 5322, практически невозможно (оно получается длиной в несколько тысяч символов и разрешает крайне редкие и странные конструкции, например, комментарии в круглых скобках внутри адреса).
Консорциум W3C в стандарте HTML5 для валидации полей ввода пошел по пути практичности и компромисса. Они предлагают лаконичный шаблон, который покрывает 99.9% реальных адресов, запрещает пробелы, двойные точки и точки на концах:
^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$
Этот шаблон отлично подходит для большинства задач, если вы хотите использовать именно регулярные выражения.
В старых версиях платформы 1С проверка e-mail через регулярные выражения обычно выполнялась через COM-объект VBScript.RegExp. У этого подхода есть огромный минус — он работает исключительно под операционной системой Windows. Если сервер 1С работает под управлением Linux (что сегодня является стандартом для крупных корпоративных баз), такой код вызовет аварийное завершение работы системы.
В современных версиях платформы 1С:Предприятие (начиная с версии 8.3.23) появилась встроенная кроссплатформенная поддержка регулярных выражений на базе стандарта ICU. Теперь мы можем использовать функции СтрНайтиПоРегулярномуВыражению и СтрЗаменитьПоРегулярномуВыражению как на Windows, так и на Linux.
Давайте посмотрим на пример реализации проверки адреса e-mail с помощью нативных механизмов платформы:
&НаКлиенте
Функция АдресПочтыКорректен(Знач ПроверяемыйАдрес) Экспорт
// Используем проверенный шаблон HTML5
Шаблон = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$";
ПозицияСовпадения = СтрНайтиПоРегулярномуВыражению(ПроверяемыйАдрес, Шаблон);
// Если функция вернула значение больше 0, значит адрес соответствует шаблону
Возврат ПозицияСовпадения > 0;
КонецФункции
Если ваша конфигурация построена на базе БСП (Библиотека стандартных подсистем), вам вообще нет необходимости самостоятельно писать регулярные выражения и «изобретать велосипед». Разработчики фирмы 1С уже реализовали надежные, протестированные и регулярно обновляемые методы валидации.
Для проверки корректности одного e-mail адреса используйте готовую функцию из общего модуля БСП:
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
АдресДляПроверки = ТекущийОбъект.Email;
Если ЗначениеЗаполнено(АдресДляПроверки) Тогда
// Функция проверяет соответствие RFC стандартам, включая поддержку кириллических адресов
Если Не ОбщегоНазначенияКлиентСервер.АдресЭлектроннойПочтыСоответствуетТребованиям(АдресДляПроверки, Ложь) Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
"Введен некорректный адрес электронной почты!",
ЭтотОбъект,
"Объект.Email",
,
Отказ
);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Давайте разберем параметры функции АдресЭлектроннойПочтыСоответствуетТребованиям:
Строка) — проверяемый адрес электронной почты.Булево) — если передать значение Истина, то адреса без доменной точки (например, admin@localhost) будут считаться валидными. По умолчанию рекомендуется передавать Ложь.Если менеджер может ввести в одну строку сразу несколько адресов (через запятую или точку с запятой), стандартная проверка регулярным выражением не справится без сложной предварительной подготовки строки. В БСП для этого случая предусмотрена другая полезная функция:
&НаСервере
Процедура ПроверитьСписокАдресов(СтрокаСАдресами)
// Функция разбивает строку на массив структур с детальной информацией по каждому адресу
МассивАдресов = ОбщегоНазначенияКлиентСервер.АдресаЭлектроннойПочтыИзСтроки(СтрокаСАдресами);
Для Каждого СведенияОбАдресе Из МассивАдресов Цикл
Если Не СведенияОбАдресе.ДоменСодержитТочку Или Не ЗначениеЗаполнено(СведенияОбАдресе.Адрес) Тогда
ВызватьИсключение "Один из введенных адресов некорректен: " + СведенияОбАдресе.Адрес;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
При решении задачи валидации e-mail в 1С придерживайтесь следующих правил:
ОбщегоНазначенияКлиентСервер.АдресЭлектроннойПочтыСоответствуетТребованиям. Она поддерживается разработчиками 1С, корректно обрабатывает международные кириллические домены и регулярно обновляется при изменении стандартов.СтрНайтиПоРегулярномуВыражению с шаблоном HTML5. Это гарантирует стабильную кроссплатформенную работу вашего кода как под Windows, так и под Linux.