隐藏带星号 (*) 的电子邮件地址 [英] Hide email address with stars (*)
问题描述
任何人都可以用简单的方法帮助我解决这个问题...我有这个邮件地址abcedf@gmail.com
.
如何转换这个邮件地址a****f@gmail.com
我尝试使用 strpos
并获得 @
但我无法获得中间值并将其更改为 ****
.任何人都可以帮助找到这个问题.
自从大约 3 年前第一次发布这个答案以来,我年纪大了,也更聪明了,所以我决定回顾一下我的片段.起初,我认为 @
上的 strpos()
会给我地址的本地"部分的长度,我可以使用 substr_replace()
简单地注入星号但是 一个有效的电子邮件地址可以在本地部分有多个 @
a> AND 多字节支持是任何实际项目的必要内容.这意味着 mb_strpos()
将足以替代 strpos()
,但在php,因此设计非正则表达式片段的卷积变得越来越没有吸引力.
如果你想看我原来的回答,你可以查看编辑历史,但我不再赞同它的使用.我的原始答案还详细说明了此页面上的其他答案如何无法混淆本地子字符串中包含 1 或 2 个字符的电子邮件地址.如果您正在考虑使用任何其他答案,但一定要针对 a@example.com
和 ab@example.com
进行测试作为初步单元测试.>
我要遵循的代码段不验证电子邮件地址;假设您的项目将使用适当的方法来验证地址,然后再允许它进入您的系统.此代码段的强大/实用之处在于它是多字节安全的,它会在所有场景中添加星号,并且当本地部分中只有一个字符时,前导字符会在 @
之前重复这样变异的地址就更难猜测了.哦,为了更简单的维护,将要添加的星号数量声明为变量.
$minFill = 4;回声 preg_replace_callback('/^(.)(.*?)([^@]?)(?=@[^@]+$)/u',函数 ($m) 使用 ($minFill) {返回 $m[1].str_repeat("*", max($minFill, mb_strlen($m[2], 'UTF-8'))).($m[3] ?: $m[1]);},$email);
输入/输出:
'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',
正则表达式:
/#pattern 分隔符^ #字符串开头(.) #capture group #1 包含第一个字符(.*?) #capture group #2 包含零个或多个字符(懒惰,又名非贪婪)([^@]?) #capture group #3 包含一个可选的单个非@ 字符(?=@[^@]+$) #要求下一个字符是@然后一个或多个@直到字符串结束/#模式分隔符u #unicode/多字节模式修饰符
回调说明:
$m[1]
第一个字符(捕获组#1)str_repeat("*", max($minFill, mb_strlen($m[2], 'UTF-8')))
使用以下方法测量捕获组 #2 的多字节长度UTF-8
编码,然后使用计算出的长度和声明的$minFill
之间的较高值,然后重复字符*
次数从max()
调用返回.($m[3] ?: $m[1])
@
之前的最后一个字符(捕获组#3);如果$m
数组中的元素为空,则使用第一个元素的值——它将始终被填充.
Anyone Help me to solve this in simple method...
I have this mail address
abcedf@gmail.com
.
How to convert this mail address
a****f@gmail.com
I tried using strpos
and get @
but I cannot get middle values and change it to ****
. Anyone help to find this problem.
Since first posting this answer nearly 3 years ago, I am older and wiser so I decided to review my snippet. At first, I thought that strpos()
on @
would get me the length of the "local" part of the address and I could use substr_replace()
to simply inject the asterisks BUT a valid email address can have multiple @
in the local part AND multibyte support is a necessary inclusion for any real-world project. This means that mb_strpos()
would be an adequate replacement for strpos()
, but there isn't yet a native mb_substr_replace()
function in php, so the convolution of devising a non-regex snippet became increasingly unattractive.
If you want to see my original answer, you can check the edit history, but I no longer endorse its use. My original answer also detailed how other answers on this page fail to obfuscate email addresses which have 1 or 2 characters in the local substring. If you are considering using any other answers, but sure to test against a@example.com
and ab@example.com
as preliminary unit tests.
My snippet to follow DOES NOT validate an email address; it is assumed that your project will use appropriate methods to validate the address before bothering to allow it into your system. The power/utility of this snippet is that it is multibyte-safe and it will add asterisks in all scenarios and when there is only a single character in the local part, the leading character is repeated before the @
so that the mutated address is harder to guess. Oh, and the number of asterisks to be added is declared as a variable for simpler maintenance.
Code: (Demo) (Regex Demo)
$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
);
Input/Output:
'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',
Regex-planation:
/ #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
Callback explanation:
$m[1]
the first character (capture group #1)str_repeat("*", max($minFill, mb_strlen($m[2], 'UTF-8')))
measure the multibyte length of capture group #2 usingUTF-8
encoding, then use the higher value between that calculated length and the declared$minFill
, then repeat the character*
the number of times returned from themax()
call.($m[3] ?: $m[1])
the last character before the@
(capture group #3); if the element is empty in the$m
array, then use the first element's value -- it will always be populated.
这篇关于隐藏带星号 (*) 的电子邮件地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!