如何使用电子邮件地址格式的preg_match PHP函数匹配域?

时间:2015-08-04 06:09:52

标签: php preg-match email-validation

以下是需要修改的脚本部分。目前,它将匹配用户提供的电子邮件地址中@之后的任何单词。我需要它能够在@之后直接匹配任何单词,或者与前面的另一个单词和点(。)匹配,例如:user@domain.com.au应该匹配域,user @ someword.domain.com也应该匹配域不管前面的.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;
}

?>

3 个答案:

答案 0 :(得分:1)

这会从电子邮件中提取域名

  1. ([a-zA-Z0-9-\_]*)\.[a-zA-Z0-9\-\_]{2,4}$
  2. @ - 包括Char:@.+?([a-zA-Z0-9-\_]*)\.[a-zA-Z0-9\-\_]{2,4}$
  3. ([a-zA-Z0-9-\_]*)这个部分在最后一个之前分组,显然是域。那是你的比赛。

    \.[a-zA-Z0-9\-\_]{2,4}$这匹配字符串末尾2到4个字符之间的字符串的最后一部分。(。com,.de,.it ...)。

    所以你总是得到点之间字符串中的倒数第二部分。

    Click me (Regex101)

    根据评论编辑:
    如果您想忽略这一事实,那些域是在第二部分写的,您需要将字符串拆分为点之间的每个部分,并尝试ping域,如果它是真的。

    编辑2:
    查看这篇文章Wikipedia Email-format。有一个有效的电子邮件格式列表。我写的正则表达式涵盖了本文中的每个示例。如果您希望人们输入无效邮件,例如&#34; paul@yahoo.mymom.com" (只是说 - >无效)你也可以期待人们写作&#34; IhaveNoEmail&#34;哪个都不会产生正确的子目录。

    所以我仍然在谈论我的观点:选择正则表达式或者给我一个真正的论据,为什么域应该写在其他地方:)。

答案 1 :(得分:0)

请注意,C4ud3x正则表达式中的{2-4}限制将禁止来自新/更长gTLDs的地址,尽管这些地址目前并不常见,但仍应视为有效。您还要考虑来自second-level domains常见的国家/地区的用户,而不要错过“真实”的用户。域名,因为你的正则表达式只捕获.org.uk。

考虑到上述情况并借用W3C recommended regex,请尝试:

[a-zA-Z0-9-_]*(\.[a-zA-Z0-9-_]{0,3})?\.([a-zA-Z0-9-_]{0,61})$ - 请参阅RegExr

当然,在尝试提取域之前,您仍应{PHP}脚本中的validate地址,以便始终获得良好的结果。

答案 2 :(得分:0)

我的同事找到了答案,他是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;
                }

这让我感到非常惊讶和感激。无论如何,感谢所有的建议和建议,我将来会在这里提出更多问题,我不会怀疑:)