在行中间用 * 替换一定数量的字符

Replace a certain number of characters with * in the middle of the line

我想将电子邮件 example@gmail.com 更改为 ex*****@gmail.com获得与替换符号相同数量的 *

我应该如何更改此代码?

preg_replace("/([_a-zA-Z0-9-]{2})([-a-z0-9]*)(@[_a-zA-Z0-9-]+)/i", "****", $model->email);

example.gmail.com - 不是电子邮件。

您的正则表达式可以很好地处理 example@gmail.com

这样的搜索字符串

如果您想使用 example.gmail.com 这样的字符串 - 您必须将表达式更改为:

preg_replace("/([_a-zA-Z0-9-]{2})([-a-z0-9]*)(.[_a-zA-Z0-9-]+)/i", "****", $model->email);

DEMO(切换到 preg_replace 选项卡)

[更新] 问题已编辑。第一个给出的示例字符串是 example.gmail.com

使用 preg_replace_callback:

$s = "example@gmail.com";
$s = preg_replace_callback(
    "/([\w-]{2})([-a-z0-9]*)(@[\w-]+)/i", 
    function ($m) { return $m[1] . str_repeat("*", strlen($m[2])). $m[3]; }, 
    $s);
echo $s; // => ex*****@gmail.com

参见PHP demo

详情:

  • [_a-zA-Z0-9]可以换成\w
  • function($m) {...}是一个回调函数,您可以在其中操作匹配数据
  • str_repeat("*", strlen($m[2])) 只是构建一个 * 字符的字符串,其次数与第 2 组长度相同。

注意

如果一定要用preg_replace,可以用

preg_replace('~(?:\G(?!^)|[\w-]{2}(?=[\w-]*@))\K[^@]~', '*', $s)

regex demo

详情

  • (?:\G(?!^)|[\w-]{2}) - 上一个成功匹配的结尾 (\G(?!^)) 或 (|) 2 个单词或 - 个字符 ([\w-]{2})后面跟着零个或多个字符,除了 word 和 - 个字符和一个 @(参见 (?=[\w-]*@)
  • \K - 省略我们匹配的内容
  • [^@] - @.
  • 以外的任何字符

您的正则表达式匹配 @ 符号,该符号在您给定的示例字符串中不可用。将其更改为 .|@ 这将匹配 .@

$email = "example.gmail.com";
$new_email  = preg_replace("/([_a-zA-Z0-9-]{2})([-a-z0-9]*)((.|@)[_a-zA-Z0-9-]+)/i", "****", $email);
echo $new_email;

DEMO