如何使 preg_match PHP 函数匹配电子邮件地址格式的域?
How to make preg_match PHP function match domain in email address format?
以下是脚本中需要修改的部分。目前,它将匹配用户提供的电子邮件地址中 @ 之后的任何单词。我需要它能够匹配 @ 之后的任何单词或前面的另一个单词和点 (.),例如: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;
}
?>
这将从电子邮件中提取域:
([a-zA-Z0-9-\_]*)\.[a-zA-Z0-9\-\_]{2,4}$
- @-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 ...)。
所以你总是会在点之间得到字符串的倒数第二部分。
根据评论编辑:
由于您想忽略域写在倒数第二部分的事实,因此您需要将字符串拆分为点之间的每个部分,并尝试 ping 域(如果它是真实的)。
编辑 2:
查看这篇文章 Wikipedia Email-format。有一个电子邮件的有效格式列表。本文中的每个示例都包含在我编写的正则表达式中。如果您期望人们输入无效邮件,例如 "paul@yahoo.mymom.com"(只是说 -> 无效),您也可以期望人们输入 "IhaveNoEmail",这也不会导致正确的子目录。
所以我仍然坚持我的观点:选择正则表达式或给我一个真正的论据,为什么域应该写在其他地方:)。
请注意,C4ud3x 正则表达式中的 {2-4} 限制会禁止来自 new/longer gTLDs which, although currently uncommon, should still be considered valid. You'll also want to consider users from countries where second-level domains 的地址很常见,并且不要错过 'real' 域,因为您的正则表达式只捕获,比如说,.org.uk.
考虑到上述内容并借鉴 W3C 的 recommended regex,尝试:
[a-zA-Z0-9-_]*(\.[a-zA-Z0-9-_]{0,3})?\.([a-zA-Z0-9-_]{0,61})$
- 见 RegExr
当然,在尝试提取域之前,您仍然应该 validate 您的 PHP 脚本中的地址,这样您总能捕获到一个好的结果。
我的同事找到了答案,他真是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;
}
这让我惊讶和感激地解开了谜语。无论如何感谢所有的建议和意见,我相信以后我还会在这里问更多的问题:)
以下是脚本中需要修改的部分。目前,它将匹配用户提供的电子邮件地址中 @ 之后的任何单词。我需要它能够匹配 @ 之后的任何单词或前面的另一个单词和点 (.),例如: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;
}
?>
这将从电子邮件中提取域:
([a-zA-Z0-9-\_]*)\.[a-zA-Z0-9\-\_]{2,4}$
- @-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 ...)。
所以你总是会在点之间得到字符串的倒数第二部分。
根据评论编辑:
由于您想忽略域写在倒数第二部分的事实,因此您需要将字符串拆分为点之间的每个部分,并尝试 ping 域(如果它是真实的)。
编辑 2:
查看这篇文章 Wikipedia Email-format。有一个电子邮件的有效格式列表。本文中的每个示例都包含在我编写的正则表达式中。如果您期望人们输入无效邮件,例如 "paul@yahoo.mymom.com"(只是说 -> 无效),您也可以期望人们输入 "IhaveNoEmail",这也不会导致正确的子目录。
所以我仍然坚持我的观点:选择正则表达式或给我一个真正的论据,为什么域应该写在其他地方:)。
请注意,C4ud3x 正则表达式中的 {2-4} 限制会禁止来自 new/longer gTLDs which, although currently uncommon, should still be considered valid. You'll also want to consider users from countries where second-level domains 的地址很常见,并且不要错过 'real' 域,因为您的正则表达式只捕获,比如说,.org.uk.
考虑到上述内容并借鉴 W3C 的 recommended regex,尝试:
[a-zA-Z0-9-_]*(\.[a-zA-Z0-9-_]{0,3})?\.([a-zA-Z0-9-_]{0,61})$
- 见 RegExr
当然,在尝试提取域之前,您仍然应该 validate 您的 PHP 脚本中的地址,这样您总能捕获到一个好的结果。
我的同事找到了答案,他真是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;
}
这让我惊讶和感激地解开了谜语。无论如何感谢所有的建议和意见,我相信以后我还会在这里问更多的问题:)