任何人都可以用简单的方法帮我解决这个问题...我有这个邮件地址
abcedf@gmail.com。
如何转换此邮件地址
a****f@gmail.com
我尝试使用strpos并获取@但我无法获取中间值并将其更改为****. 任何人都可以帮助找到这个问题。
自从大约 3 年前第一次发布这个答案以来,我年纪大了,也更聪明了,所以我决定回顾一下我的片段。起初,我认为strpos()on@会让我得到地址的“本地”部分的长度,我可以substr_replace()用来简单地注入星号但是一个有效的电子邮件地址可以@在本地部分有多个并且多字节支持是必要的包含任何现实世界的项目。这意味着这mb_strpos()将是一个足够的替代品strpos(),但mb_substr_replace()在 php 中还没有本机函数,因此设计非正则表达式片段的卷积变得越来越没有吸引力。
如果你想看我的原答案,你可以查看编辑历史,但我不再认可它的使用。我的原始答案还详细说明了此页面上的其他答案如何无法混淆本地子字符串中包含 1 或 2 个字符的电子邮件地址。如果你正在使用的任何其他答案考虑,但一定要对测试a@example.com和ab@example.com作为初步的单元测试。
我要遵循的代码段不验证电子邮件地址;假设您的项目将使用适当的方法来验证地址,然后再允许它进入您的系统。此代码段的强大/实用之处在于它是多字节安全的,它会在所有场景中添加星号,并且当本地部分中只有一个字符时,前导字符会在 之前重复,@这样变异的地址就更难找到了猜测。哦,为了更简单的维护,要添加的星号数量被声明为一个变量。
$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
);
Run Code Online (Sandbox Code Playgroud)
输入输出:
'a@example.com' => 'a****a@example.com',
'ab@example.com' => 'a****b@example.com',
'abc@example.com' => 'a****c@example.com',
'abcd@example.com' => 'a****d@example.com',
'abcde@example.com' => 'a****e@example.com',
'abcdef@example.com' => 'a****f@example.com',
'abcdefg@example.com' => 'a*****g@example.com',
'?@example.com' => '?****?@example.com',
'??@example.com' => '?****?@example.com',
'???@example.com' => '?****?@example.com',
'???????@example.com' => '?*****?@example.com',
'"a@tricky@one"@example.com' => '"************"@example.com',
Run Code Online (Sandbox Code Playgroud)
正则表达式:
/ #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
Run Code Online (Sandbox Code Playgroud)
回调说明:
$m[1]str_repeat("*", max($minFill, mb_strlen($m[2], 'UTF-8')))UTF-8编码测量捕获组 #2 的多字节长度,然后使用计算的长度和声明的 之间的较高值$minFill,然后重复调用*返回的字符次数max()。($m[3] ?: $m[1])@(捕获组#3)之前的最后一个字符;如果$m数组中的元素为空,则使用第一个元素的值——它将始终被填充。