проверка preg_match неанглийских адресов электронной почты (международных доменных имен)

Мы все знаем, что проверка адреса электронной почты является очень деликатной темой, и существует множество мнений о том, как лучше всего с ней справиться без кодирования для всего RFC. Но с 2009 года это стало еще сложнее, и я пока не видел, чтобы кто-нибудь решал вопрос с IDN.

Вот что я использовал:

preg_match(/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,6}\z/i)

Который будет работать для большинства адресов электронной почты, но что, если мне нужно будет соответствовать нелатинский адрес электронной почты? например: bob @ china. 中國 или bob@russia.рф

Посмотрите Вот для полного списка. (Обратите внимание на все нелатинские доменные расширения внизу списка.)

Информацию на эту тему можно найти Вот и я думаю, что они говорят, что эти новые символы будут просто читаться как «.xn — fiqz9s» и «.xn — p1ai» на машинном уровне, но я не уверен на 100%.

Если это так, означает ли это единственное изменение, которое мне нужно рассмотреть, чтобы сделать в моем коде следующее? (Для доменных расширений, таких как .travelersinsurance и .sandvikcoromant)

preg_match(/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,20}\z/i)

ВНИМАНИЕ: Это не связано с обсуждением на этой странице. Использование регулярного выражения для проверки адреса электронной почты

0

Решение

Подумайте: каждый раз, когда вы создаете свое собственное новое регулярное выражение без проверки адресов в соответствии с полной спецификацией RFC, вы только усугубляете ситуацию с использованием «экзотических» адресов электронной почты в Интернете. Вы изобретаете какой-то новый специальный суб-набор или расширенный набор официальной спецификации RFC; это означает, что у вас будут либо ложные срабатывания, либо ложные отрицания, либо и то и другое, вы будете отказывать людям в использовании их реальных адресов, потому что ваше регулярное выражение не учитывает их правильно, или вы примете адреса, которые на самом деле являются недействительными.

Добавьте к этому, что даже если адрес является синтаксически действительным, это все равно не означает, что a) адрес фактически (все еще) существует, b) принадлежит этому пользователю или c) может фактически получать электронную почту. В схеме предоставления грантов проверка синтаксиса является крайне незначительной проблемой.

Если вы вообще собираетесь проверять синтаксис, либо сделайте очень грубую общую проверку, которая обязательно не отклонит никаких действительных адресов (например, /.+@.+/), или же проверять в соответствии со всеми правилами RFC; не делайте промежуточных проверок типа «строгий, но не очень», которые вы только что придумали.

3

Другие решения

Я буду придерживаться проверенного и верного предложения, чтобы вы отправили им письмо с подтверждением. Нет необходимости в необычном регулярном выражении, которое нужно будет обновлять снова и снова. Просто предположите, что они знают свой адрес электронной почты и дайте им ввести его.

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

2

Вот что я в итоге придумал.

preg_match(/^[\pL\pM*+\pN._%+-]+@[\pL\pM*+\pN.-]+\.[\pL\pM*+]{2,20}\z/u)

Это использует регулярные выражения Unicode, такие как \ рх, \ Рм * + а также \ пН чтобы помочь мне разобраться с символами и цифрами на любом языке.

\ рх Любые буквы на любом языке, прописные или строчные.

\ Рм * + Соответствует нулю или большему количеству кодов, которые объединяют метки. Символ, предназначенный для объединения с другим символом (например, акценты, умлауты, заключенные в рамки и т. Д.).

\ пН Любой номер.

Выражение выше будет отлично работать для обычных адресов электронной почты, таких как [email protected] и какофонических адресов электронной почты, таких как a.s 中 3_yÄh মহাজোটের oo 文% 网 +d-fελληνικά@πyÄhooαράδειγμα.δοκιμή.

Не то, чтобы я не доверял людям, чтобы они могли вводить свои собственные адреса электронной почты, но люди действительно делают ошибки, и я могу использовать этот код в других ситуациях. Например: мне нужно дважды проверить целостность существующего списка из 10 000 адресов электронной почты. Кроме того, меня всегда учили НЕ доверять пользовательскому вводу и ВСЕГДА фильтровать.

ОБНОВИТЬ

Я только что обнаружил, что, хотя это прекрасно работает при тестировании на таких сайтах, как phpliveregex.com и локально при синтаксическом анализе обычной строки для содержимого utf-8 он не работает должным образом с полями электронной почты, потому что браузеры конвертируют поля этого типа содержимого в обычную латиницу. Таким образом, адрес электронной почты, такой как bob @ china. 中國 или bob@russia.рф, конвертируется перед получением сервером на адрес [email protected] или [email protected]. Единственное, чего мне действительно не хватало в моем первоначальном фильтре, было включение дефисов из расширения домена.

Вот окончательная версия:

preg_match('/^[a-z0-9%+-._]+@[a-z0-9-.]+\.[a-z0-9-]{2,20}\z/i');
-1
По вопросам рекламы [email protected]