Как проверить не-английский (UTF-8) кодированный адрес электронной почты в Javascript и PHP?

Часть веб-сайта, в котором я сейчас работаю, содержит процесс регистрации, где пользователи должны указать свой адрес электронной почты. Совсем недавно я узнал, что возможно использование доменов, не связанных с ascii (например, электронная почта). Мой бэкенд - это кодировка utf-8, в которой я ожидаю, что любые пользователи (с разными локалями) должны иметь возможность вводить свой адрес электронной почты, но не знают, как проверить этот вид адреса электронной почты.

В настоящее время я тестирую инструменты jquery и правильно проверяет английский адрес электронной почты, но не проверяет электронную почту без ascii. Также мне нужно сделать то же самое на стороне сервера с php. Есть ли регулярное выражение, которое может подтвердить этот адрес электронной почты?

Я пробовал это, но он не работает в jquery-инструментах (это просто пример для демонстрации, я тоже этого не понимаю)

闪闪 发光 @闪闪 发光.com

Также, когда они наберут свой английский адрес электронной почты ([email protected]) со своим собственным IME. Может ли это быть подтверждено с текущим регулярным выражением, которое мы имеем для проверки английской почты. В настоящее время мне не нужно беспокоиться, если это письмо существует для нет.

Спасибо

Ответ 1

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

Более вероятно, что пользователь (случайно или намеренно) будет вводить неправильный адрес электронной почты, чем в недопустимом, поэтому на самом деле проверка является большой работой для очень мало пользы, с возможными издержками, если вы делаете это неправильно.

Я бы рекомендовал вам просто проверить наличие символа @ на клиенте, а затем отправить подтверждение на подтверждение, чтобы проверить его; это наиболее практичный способ проверки, и он подтверждает, что адрес правильный.

Ответ 2

Так как PHP PHP имеет сборку для проверки адресов электронной почты. Но я не уверен, работает ли он для кодированных строк UFT-8:

echo filter_var($email, FILTER_VALIDATE_EMAIL);

В исходный исходный код PHP вы найдете reg exp для проверки электронной почты, это можно использовать для ручной проверки при использовании PHP < 5.2.

Обновить

idn_to_ascii() можно использовать для "Преобразовать доменное имя в форму IDNA ASCII". Которая затем может быть проверена с помощью filter_var($email, FILTER_VALIDATE_EMAIL);

// International domains
if (function_exists('idn_to_ascii') && strpos($email, '@') !== false) {
    $parts = explode('@', $email);
    $email = $parts[0].'@'.idn_to_ascii($parts[1]);
}
$is_valid = filter_var($email, FILTER_VALIDATE_EMAIL);

Ответ 3

Как предложили Mario, немного поиграв, я применил следующее регулярное выражение для проверки нестандартного адреса электронной почты:

^([\p{L}\.\-\d]+)@([\p{L}\-\.\d]+)((\.(\p{L}){2,63})+)$

Он будет проверять любой правильный адрес электронной почты со всеми типами символов Юникода, с ограничениями ДВУ от 2 до 63 символов.

Пожалуйста, проверьте его и сообщите мне, есть ли какие-либо недостатки.

Пример онлайн

Ответ 4

reg exp может быть примерно таким:

[^ ][email protected][^ ]+\.[^ ]{2,6}

Ответ 5

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

Проверка на стороне клиента

if(!$.trim(value).length) {
    return false;
}
else {

    AtPos = value.indexOf("@");
    StopPos = value.lastIndexOf(".");

    if (AtPos == -1 || StopPos == -1) {
        return false;
    }

    if (StopPos < AtPos) {
        return false;
    }

    if (StopPos - AtPos == 1) {
        return false;
    }

    return true;
}

Проверка серверов

if(!isset($_POST['emailaddr']) || trim($_POST['emailaddr']) == "") {
    //Error: Email required
}
else {
    $atpos = strpos($_POST['emailaddr'],'@');
    $stoppos = strpos($_POST['emailaddr'],'.');

    if(($atpos === false) || ($stoppos === false)) {
        //Error: invalid email
    }
    else {
        if($stoppos < $atpos) {
            //Error: invalid email
        }
        else {
            if (($stoppos-$atpos) == 1) {
            //Error: invalid email
        }
    }
}

Хотя у него все еще есть дыры в петле, я думаю, что пользователи не будут обманывать это. Также реальная валидация требуется для серьезных вещей, как это предлагает "Джереми Бэнкс".

Надеюсь, это будет полезно и для кого-то другого.

Спасибо и уважаем всех

Ответ 6

На эту тему мне понравилась эта страница настолько, что я настроил в блоге, подверженном сайтам, которые делают валидацию неверными (вклады, полученные с благодарностью - не позволяйте вам быть на нем!).

Что касается использования регулярных выражений, те, которые говорят "не так", имеют тенденцию быть легкими на альтернативы, а проверка TBH на последнюю букву RFC на самом деле не является критичной - например, в то время как noddy+!#$%&'*-/=?+_{}|[email protected] является совершенно правильный адрес, не слишком необоснованно отклонять его, учитывая, что удивительно большая часть пользователей не может даже правильно набрать "hotmail". Некоторые домены также весьма ограничивают имена пользователей, особенно hotmail. Поэтому я выступаю за регулярные выражения, которые явно разумны, и мой любимый источник для этого - эта страница, хотя мне не нравится их текущий JS 'winner', и это помогло бы, если бы они создали публичную тестовую страницу.

jQuery validate plugin использует это регулярное выражение, что интересно построенный, довольно похожий по стилю (но меньший!) на экс-попугай (фактически мой интернет-провайдер!), связанный с @powtac.

Ответ 7

Что это значит:

mb_internal_encoding("UTF-8");
mb_regex_encoding("UTF-8");
mb_ereg('[\w][email protected][\w]+\.com',$mail,'UTF-8');