
本文介绍一种基于空格分词 + 类型识别的 PHP 实现方案,可精准识别并掩码字符串中的手机号(如 123-456-7890 → 123-456-7xxx)和邮箱(如 user@example.com → usexxx@xxxple.com),同时保留非敏感内容原样输出。
本文介绍一种基于空格分词 + 类型识别的 php 实现方案,可精准识别并掩码字符串中的手机号(如 `123-456-7890` → `123-456-7xxx`)和邮箱(如 `user@example.com` → `usexxx@xxxple.com`),同时保留非敏感内容原样输出。
在处理用户输入或日志数据时,常需对隐私信息(如电话号码、邮箱地址)进行脱敏,但又不能破坏原始字符串结构(例如保留括号、空格、连字符、+号等格式)。直接使用全局正则替换容易误伤非敏感内容(如 123 string 456 中的数字),因此更稳妥的策略是:按空格切分 → 逐段识别 → 分类掩码。
以下是一个健壮、可读性强的 PHP 实现:
<?php function maskSensitiveParts(string $input): string
{
$parts = explode(' ', $input);
return implode(' ', array_map(function (string $part): string {
// 情况 1:标准邮箱格式(含 @ 且通过 filter_var 验证)
if (filter_var($part, FILTER_VALIDATE_EMAIL)) {
[$local, $domain] = explode('@', $part, 2);
$maskedLocal = strlen($local) > 3
? substr($local, 0, -3) . 'xxx'
: str_repeat('x', strlen($local)); // 防御极短用户名(如 a@b.c)
$maskedDomain = strlen($domain) > 3
? 'xxx' . substr($domain, 3)
: str_repeat('x', strlen($domain));
return $maskedLocal . '@' . $maskedDomain;
}
// 情况 2:疑似电话号码 —— 长度 ≥ 6 且至少含 1 个数字(排除纯字母/符号段)
if (strlen($part) >= 6 && preg_match('/\d/', $part)) {
// 仅掩码末三位为 'xxx',保留前缀所有字符(含 +、(、-、空格等)
return substr($part, 0, -3) . 'xxx';
}
// 其他情况:不处理(如 'Hello!', 'fgbv', 'string')
return $part;
}, $parts));
}
// 示例用法
$input = '(111) 222-3333 fgbv 1112223333 111 222-3333 fghgg 111-222-3333 <a href="mailto:test@example.com">[email protected]</a> fghntyjn (111)2223333 +11234567890 1-8002353551 123-456-7890 -Hello! +1 - 1234567890';
echo maskSensitiveParts($input);
// 输出:(111) 222-3xxx fgbv 1112223xxx 111 222-3xxx fghgg 111-222-3xxx <a href="mailto:test@example.com">[email protected]</a> fghntyjn (111)2223xxx +11234567xxx 1-8002353xxx 123-456-7xxx -Hello! +1 - 1234567xxx
✅ 关键设计说明:
-
邮箱掩码逻辑:本地部分(
@前)保留前 N−3 位 +xxx;域名部分(@后)以xxx替换开头 3 位(如example.com→xxxmple.com),兼顾可读性与安全性; -
电话掩码逻辑:不依赖复杂正则匹配格式,而是基于「长度 + 数字存在」双重判断,避免误伤
ID:123或v2.4.5等非电话内容; -
鲁棒性增强:对超短邮箱(如
a@b.co)做边界防护,防止substr负偏移报错; -
格式零破坏:原始空格、标点、HTML 标签(如
<a></a>中的邮箱未被解析,因$part是纯文本分段)均不受影响。
⚠️ 注意事项:
- 此方案假设敏感字段以空格分隔。若存在无空格连接(如
abc(111)222-3333def),需先用正则提取再处理; - 若需支持 HTML 内嵌邮箱(如示例中的
<a></a>标签),应先用 DOM 解析器提取文本内容,而非直接分词; - 生产环境建议结合
FILTER_FLAG_EMAIL_UNICODE(PHP 8.2+)提升国际化邮箱兼容性; - 敏感数据最终应遵循 GDPR / 《个人信息保护法》要求,在存储层也做加密或哈希,前端掩码仅为辅助展示。
该方法简洁、可维护、易测试,适合日志脱敏、客服工单展示、审计输出等通用场景。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











