在 PHP 中用星号 (*) 提示或部分隐藏电子邮件地址

问题描述 投票:0回答:7

我有这个邮件地址

[email protected]

如何转换成这个邮件地址

a****[email protected]

我尝试使用

strpos
并获得
@
但我无法获得中间值并将其更改为
****

php string formatting
7个回答
10
投票

起初,我认为

strpos()
上的
@
可以获得地址“本地”部分的长度,我可以使用
substr_replace()
来简单地注入星号,但是 一个有效的电子邮件地址可以有多个
 @
在本地部分
并且多字节支持是任何实际项目的必要包含。 这意味着
mb_strpos()
将足以替代
strpos()
,但 php 中还没有原生
mb_substr_replace()
函数,因此设计非正则表达式片段的卷积变得越来越没有吸引力。

如果你想看我原来的答案,你可以查看编辑历史,但我不再认可它的使用。 我原来的答案还详细介绍了此页面上的其他答案如何无法混淆本地子字符串中包含 1 或 2 个字符的电子邮件地址。 如果您正在考虑使用任何其他答案,但请务必针对

[email protected]
[email protected]
作为初步单元测试进行测试。

我要遵循的代码片段不会验证电子邮件地址;假设您的项目将使用适当的方法来验证地址,然后再允许它进入您的系统。 该代码片段的强大功能/实用性在于它是多字节安全的,并且它将在所有情况下添加星号,并且当本地部分中只有单个字符时,前导字符会在

@
之前重复,以便变异地址更难猜测。 哦,为了更简单的维护,要添加的星号数量被声明为变量。

代码:(演示)(PHP7.4+演示)(正则表达式演示

$minFill = 4;
echo preg_replace_callback(
         '/^(.)(.*?)([^@]?)(?=@[^@]+$)/u',
         function ($m) use ($minFill) {
              return $m[1]
                     . str_repeat("*", max($minFill, mb_strlen($m[2], 'UTF-8')))
                     . ($m[3] ?: $m[1]);
         },
         $email
     );

输入/输出:

'[email protected]'              => 'a****[email protected]',
'[email protected]'             => 'a****[email protected]',
'[email protected]'            => 'a****[email protected]',
'[email protected]'           => 'a****[email protected]',
'[email protected]'          => 'a****[email protected]',
'[email protected]'         => 'a****[email protected]',
'[email protected]'        => 'a*****[email protected]',
'Ф@example.com'              => 'Ф****Ф@example.com',
'ФѰ@example.com'             => 'Ф****Ѱ@example.com',
'ФѰД@example.com'            => 'Ф****Д@example.com',
'ФѰДӐӘӔӺ@example.com'        => 'Ф*****Ӻ@example.com',
'"a@tricky@one"@example.com' => '"************"@example.com',

正则表达式解释:

/            #pattern delimiter
^            #start of string
(.)          #capture group #1 containing the first character
(.*?)        #capture group #2 containing zero or more characters (lazy, aka non-greedy)
([^@]?)      #capture group #3 containing an optional single non-@ character
(?=@[^@]+$)  #require that the next character is @ then one or more @ until the end of the string
/            #pattern delimiter
u            #unicode/multibyte pattern modifier

回调说明:

  • $m[1]

    第一个字符(捕获组#1)
  • str_repeat("*", max($minFill, mb_strlen($m[2], 'UTF-8')))

    使用
    UTF-8
    编码测量捕获组#2的多字节长度,然后使用计算出的长度和声明的
    $minFill
    之间的较高值,然后重复字符
    *
    从返回的次数
    max()
    致电。
  • ($m[3] ?: $m[1])

    @
    之前的最后一个字符(捕获组#3);如果
    $m
    数组中的元素为空,则使用第一个元素的值 - 它将始终被填充。

对于寻求不太复杂的方法的任何人,以下

preg_replace()
调用将以 1 对 1 的方式替换电子邮件的本地部分,从第二个(非最后一个)字符到倒数第二个(非第一个)字符使用
\G
(继续)元字符进行时尚。在某些边缘情况下,此技术无法编辑任何字符 - 因此请谨慎使用。

echo preg_replace("/(?:^.\K|\G(?!^))[^@](?!@)/u", '*', $email);

输入/输出:

'[email protected]'              => '[email protected]',               // not good
'[email protected]'             => '[email protected]',              // not good
'[email protected]'            => 'a*[email protected]',
'[email protected]'           => 'a**[email protected]',
'[email protected]'          => 'a***[email protected]',
'[email protected]'         => 'a****[email protected]',
'[email protected]'        => 'a*****[email protected]',
'Ф@example.com'              => 'Ф@example.com',               // not good
'ФѰ@example.com'             => 'ФѰ@example.com',              // not good
'ФѰД@example.com'            => 'Ф*Д@example.com',
'ФѰДӐӘӔӺ@example.com'        => 'Ф*****Ӻ@example.com',
'"a@tricky@one"@example.com' => '"a@tricky@one"@example.com',  // not good

2
投票

这是简单版本:

$em = '[email protected]'; // 'a****[email protected]'
$em = '[email protected]'; // 'a*******[email protected]'

使用 PHP 字符串函数

$stars = 4; // Min Stars to use
$at = strpos($em,'@');
if($at - 2 > $stars) $stars = $at - 2;
print substr($em,0,1) . str_repeat('*',$stars) . substr($em,$at - 1);

1
投票

迟到的答案,但你可以使用:

$email = "[email protected]";
print preg_replace_callback('/(\w)(.*?)(\w)(@.*?)$/s', function ($matches){
    return $matches[1].preg_replace("/\w/", "*", $matches[2]).$matches[3].$matches[4];
}, $email);

# a****[email protected]

1
投票

正则表达式:

^.\K[a-zA-Z\.0-9]+(?=.@)
可以改成这样
^[a-zA-Z]\K[a-zA-Z\.0-9]+(?=[a-zA-Z]@)

1.

^.\K
这将匹配电子邮件的第一个字符,
\K
将重置匹配

2.

[a-zA-Z\.0-9]+(?=.@)
这将匹配字符串并向前查找任何字符,然后
@

在代码的第二条语句中,我们创建相同的编号。的

*
作为编号。匹配的字符数。

在第三条语句中,我们使用

preg_replace
删除与
*
's

匹配的字符串

在这里试试这个代码片段

<?php
$string='[email protected]';
preg_match('/^.\K[a-zA-Z\.0-9]+(?=.@)/',$string,$matches);//here we are gathering this part bced

$replacement= implode("",array_fill(0,strlen($matches[0]),"*"));//creating no. of *'s
echo preg_replace('/^(.)'.preg_quote($matches[0])."/", '$1'.$replacement, $string);

输出:

a****[email protected]


0
投票

在某些情况下,您希望显示部分电子邮件以向用户提示其电子邮件 ID。如果您正在寻找类似的内容,您可以使用电子邮件用户名的半个字符并替换为某些字符。这是 PHP 函数 ,您可以将其用于您的项目 隐藏电子邮件地址

<?php
function hide_email($email) {
        // extract email text before @ symbol
        $em = explode("@", $email);
        $name = implode(array_slice($em, 0, count($em) - 1), '@');

        // count half characters length to hide
        $length = floor(strlen($name) / 2);

        // Replace half characters with * symbol
        return substr($name, 0, $length) . str_repeat('*', $length) . "@" . end($em);
}

echo hide_email("[email protected]");
?>

// 输出:cont****@gmail.com


0
投票

可以帮助别人。

<?php
echo  hide_mail( "[email protected]" );

function hide_mail($email) {
    $hideAfter = 1;
    $mail_part = explode("@", $email);
    $part1 = substr($mail_part[0],0,$hideAfter);
    $part2 = substr($mail_part[0],$hideAfter);
    $part2 = str_repeat("*", strlen($part2));
    $mail_part[0] = $part1.$part2;
    return implode("@", $mail_part);
}

0
投票

我找到了一个更简单的解决方案。请记住,这不是验证,需要单独完成。

$email = '[email protected]';

preg_match('/^(.)(.+)([@])(.+)$/i', $email, $matches); 

$matches[2] = preg_replace('/./', '*', $matches[2]);

echo $matches[1] . $matches[2] . $matches[3] . $matches[4];

// output should be s*********@gmail.com.

这是我使用的页面的链接。它使用起来相当简单,并且有一些功能可供您复制和粘贴。

https://www.phpliveregex.com/

© www.soinside.com 2019 - 2024. All rights reserved.