Как заставить PHP-функцию preg_match соответствовать домену в формате адреса электронной почты?

Ниже приведена часть скрипта, которую необходимо изменить. В настоящее время он будет соответствовать любому слову, стоящему непосредственно после @ в адресе электронной почты, указанном пользователем. Мне нужно, чтобы он мог сопоставлять любое слово либо непосредственно после @, либо с другим словом и точкой (.), предшествующей, например: [email protected] должен соответствовать домену, [email protected] также должен соответствовать домену независимо от .someword впереди (который меняет пользователя на пользователя и существует для некоторых, но не для других.

PHP-код:

preg_match('|@([0-9a-zA-Z]+)\.|i', $username, $match);

А ниже весь код с конфиденциальной информацией, измененной в целях безопасности.

<?php

// PHP code in child theme of WordPress multisite network functions.php

add_filter( 'authenticate', 'external_auth', 10, 3 );
add_filter( 'login_redirect', 'ds_login_redirect', 10, 3 );

function external_auth( $user, $username, $password ){

    // Make sure a username and password are present for us to work with
    if($username == '' || $password == '') return;    

    // Try to log into the external service or database with username and password

    $args = array(
        'method' => 'POST',
        'timeout' => 45,
        'redirection' => 5,
        'httpversion' => '1.0',
        'blocking' => true,
        'headers' => array(),
        'body' => array( 'username' => $username, 'password' => $password ),
        'cookies' => array()
        );

    $ext_auth = wp_remote_post("http://auth-server:port-number/api-token-auth/",$args);

    // if external authentication was successful
    if($ext_auth['response']['code'] == 200) {

        $userobj = new WP_User();
        $user = $userobj->get_data_by( 'login', $username ); 
        // Does not return a WP_User object :(
        $user = new WP_User($user->ID); 
        // Attempt to load up the user with that ID

        if( $user->ID == 0 ) {
                // The user does not currently exist in the WordPress user table.
                // If you do not want to add new users to WordPress if they do not
                // already exist uncomment the following line and remove the user creation code
                //$user = new WP_Error( 'denied', __("ERROR: Not a valid user for this system") );

                // Setup the minimum required user information
                $new_user_id =  wpmu_create_user($username, $password, $username); 
                // A new user has been created


                preg_match('|@([0-9a-zA-Z]+)\.|i', $username, $match);

                $path = '/'.$match[1].'/';

                $domain = 'the-wordpress-network-site.com';

                // Figure out their blog to add permission to 
                $blog_id = get_blog_id_from_url ( $domain, $path );

                // Specify their role 
                $role = 'subscriber';

                // Give the user access to their blog.
                add_user_to_blog($blog_id, $new_user_id, $role);

                // Load the new user info
                $user = new WP_User ($new_user_id);
        } 

    }else if($ext_auth['response']['code'] == 400){
        $user = new WP_Error( 'denied', __("ERROR: User/pass bad") );
    }

    // Comment this line if you wish to fall back on WordPress authentication
    remove_action('authenticate', 'wp_authenticate_username_password', 20);

    return $user;   
}

function ds_login_redirect( $redirect_to, $request_redirect_to, $user )
{
    if ($user->ID != 0) {
        $user_info = get_userdata($user->ID);
        if ($user_info->primary_blog) {
            $primary_url = get_blogaddress_by_id($user_info->primary_blog) . 'index/';
            if ($primary_url) {
                //echo $primary_url; die();
                wp_redirect($primary_url);
                die();
            }
        }
    }

    return $redirect_to;
}

?>

person WhitePointerNet    schedule 04.08.2015    source источник
comment
возможный дубликат Как проверить электронную почту в PHP?   -  person mmm    schedule 04.08.2015
comment
@mmm Он не говорит о проверке. Он говорит о получении домена по почте. Это разница.   -  person C4d    schedule 04.08.2015


Ответы (3)


Это приведет к извлечению домена из электронной почты:

  1. ([a-zA-Z0-9-\_]*)\.[a-zA-Z0-9\-\_]{2,4}$
  2. @-Char включено: @.+?([a-zA-Z0-9-\_]*)\.[a-zA-Z0-9\-\_]{2,4}$

([a-zA-Z0-9-\_]*) этот группирует часть перед последней, очевидно, домен. Это ваш матч.

\.[a-zA-Z0-9\-\_]{2,4}$ соответствует последней части строки между 2 и 4 символами в конце строки (.com, .de, .it...).

Таким образом, вы всегда будете получать вторую последнюю часть строки между точками.

Нажмите на меня (Regex101)


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

Редактировать 2:
Прочтите эту статью Формат электронной почты Википедии. Существует список допустимых форматов для электронных писем. Каждый пример в этой статье покрывается регулярным выражением, которое я написал. Если вы ожидаете, что люди будут вводить недопустимые письма, такие как «[email protected]» (просто сказать -> недействительно), вы также можете ожидать, что люди напишут «IhaveNoEmail», что также не приведет к правильному подкаталогу.

Так что я все еще на своем: выберите регулярное выражение или дайте мне реальный аргумент, почему домен должен быть записан где-то еще :).

person C4d    schedule 04.08.2015
comment
Извините, я не упомянул, что .com может быть .com.au или .co.nz, так как это происходит на международном сайте. - person WhitePointerNet; 04.08.2015
comment
Без проблем. Если это решило вашу проблему, отметьте это как правильное. В противном случае расскажите нам о своих проблемах :). - person C4d; 04.08.2015
comment
Так что да, php, который вы там сделали, даст предпоследнюю часть между точками. Мне нужно, чтобы это работало, если оно предпоследнее или третье (или больше), например: [email protected] или [email protected] должны оба возвращать совпадение для домена. Мой коллега предложил, может быть, нам нужно где-то иметь массив? Я недостаточно хорошо разбираюсь в php, чтобы понять, как это сделать .. :) Еще раз ура - person WhitePointerNet; 04.08.2015
comment
[email protected] невозможно! Домен всегда находится на 2-й последней части. Это всегда формат [email protected] ИЛИ [email protected] ИЛИ [email protected]. - person C4d; 04.08.2015
comment
Спасибо, но эти доменные имена не обязательно ссылаются на что-то, что уже есть. Это могут быть невозможные адреса электронной почты, но моя потребность прочитать и сопоставить нужную часть остается. Кроме того, 2-й последний всегда является доменом, который не охватывает .com.au или .edu.au и т. д., в списке пользователей есть как те, так и .com адреса, которые исчисляются тысячами. Я не могу изменить их соглашение об именах для пользователей, как бы нелогично это ни было. - person WhitePointerNet; 05.08.2015
comment
Итак, вы хотите получить домен даже из недопустимых форматов электронной почты? Потому что [email protected] не может быть реальным. Единственным исключением может быть реальный домен под названием www.google.pickup.com. Но это не будет указателем на www.google.com Тогда электронная почта будет [email protected]. Проверить мои изменения - person C4d; 05.08.2015
comment
Да, действительность электронной почты не то, что мне нужно; это просто имя пользователя с этим ужасным форматом электронной почты, который они использовали. Этот скрипт на самом деле является частью более крупного сценария в дочерней теме моей многосайтовой сети WP, который получает статус 200 с внешнего сервера аутентификации. Все остальное работает, это просто надоедливый бит preg_match, который меня действительно смущает :) - person WhitePointerNet; 05.08.2015
comment
Не могу понять, почему, но ладно. Добавил еще один способ. То, что вы говорите, похоже на проверку части перед @ для домена. Звучит нелогично для меня. Но точно можно сделать. Как сказано выше, вам нужно будет пинговать каждое слово, так как С# не может знать, что такое домен или нет. - person C4d; 05.08.2015
comment
Извините, здесь что-то теряется в переводе. Мне не нужно на самом деле пинговать домен. они всего лишь ярлык. Сценарий, который у меня есть, соответствует части имени пользователя, введенного пользователем при входе в систему, которая относится к подпапке моего сайта. Например: пользователь с именем входит в систему как [email protected], а другой пользователь входит как [email protected]. - person WhitePointerNet; 05.08.2015
comment
Они оба прекрасно аутентифицируются в другом месте скрипта, эта часть preg_match используется только для извлечения имени подпапки из имени пользователя, поэтому результат $match1 используется для перенаправления их на домашнюю страницу этой подпапки. перенаправление уже работает только в настоящее время только для [email protected], а не для последнего - person WhitePointerNet; 05.08.2015
comment
Итак, ваши пользователи будут перенаправлены в папки, которые названы доменами? Например. пользователь с [email protected] будет перенаправлен на www.yourwebsite.com/gmx? - person C4d; 05.08.2015
comment
Точно :) Вот скрипт в контексте: - person WhitePointerNet; 05.08.2015
comment
ТОГДА друг мой, почему ты не можешь использовать пункт 1 или 2 в моем ответе? Я дополню свой ответ. - person C4d; 05.08.2015
comment
Я добавил его около 6 минут назад, извините, у меня возникли проблемы с копированием кода и его принятием. - person WhitePointerNet; 05.08.2015

Обратите внимание, что ограничение {2-4} в регулярном выражении C4ud3x запрещает использование адресов из новых/более длинных gTLD, которые, хотя и редко встречаются в настоящее время, тем не менее должны считаться действительными. Вы также можете рассмотреть пользователей из стран, где распространены домены второго уровня, и не пропустите «настоящий» домен, потому что ваше регулярное выражение захватывает, скажем, .org.uk.

С учетом вышеизложенного и заимствования из рекомендованного регулярного выражения< /а> попробуйте:

[a-zA-Z0-9-_]*(\.[a-zA-Z0-9-_]{0,3})?\.([a-zA-Z0-9-_]{0,61})$ – см. RegExr

Конечно, вы все равно должны проверить адрес в своем PHP-скрипте перед пытаясь извлечь домен, чтобы вы всегда получали хороший результат.

person Sean K. Gabriel    schedule 05.08.2015
comment
Спасибо за ответы :) Я проведу несколько тестов и сообщу вам результат. - person WhitePointerNet; 06.08.2015

Мой коллега нашел ответ, он гений PHP!

Вместо этого кода в вопросе:

preg_match('|@([0-9a-zA-Z]+)\.|i', $username, $match);

                $path = '/'.$match[1].'/';

                $domain = 'the-wordpress-network-site.com';

Теперь код гласит:

$domain_end = explode('@', $username);
                $match = explode('.', $domain_end[1]);
                $domain = 'the-wordpress-network-site.com';
                foreach ($match as $blog_key){
                    $path = '/'.$blog_key.'/';
                    $blog_id = get_blog_id_from_url ( $domain, $path );
                    if ($blog_id != 0) break;
                }

К моему изумлению и благодарности, это разрешило загадку. В любом случае спасибо за все предложения и советы, я все еще буду здесь, чтобы задать еще много вопросов в будущем, я не сомневаюсь :)

person Community    schedule 07.08.2015
comment
Обновлять! Посмотрите, как появился этот код. Все рабочая версия! stackoverflow.com/questions/35908534/ - person WhitePointerNet; 10.03.2016