
本文介绍使用 php 将 html 邮箱链接按域名后缀(如 gmail.com、yahoo.com)分组,同后缀邮箱合并为竖线分隔的单行字符串,并保持字母序排列。
本文介绍使用 php 将 html 邮箱链接按域名后缀(如 gmail.com、yahoo.com)分组,同后缀邮箱合并为竖线分隔的单行字符串,并保持字母序排列。
在网页爬取或数据清洗场景中,常需对嵌入 HTML 标签(如 Cloudflare 加密邮箱 <a> 元素)的邮箱地址进行结构化处理。核心需求是:按邮箱域名后缀(即 @ 后部分)分组 → 组内按原始 HTML 字符串字典序排序 → 每组拼接为 | 分隔的单行字符串。
以下为完整、健壮的实现方案(兼容含 HTML 标签的邮箱字符串):
<?php
$emails = [
'<a class="__cf_email__" data-cfemail="8afbfdefcaf3ebe2e5e5a4e9e5e7" href="/cdn-cgi/l/email-protection">[email protected]</a>',
'<a class="__cf_email__" data-cfemail="7903011a391e14181015571a1614" href="/cdn-cgi/l/email-protection">[email protected]</a>',
'<a class="__cf_email__" data-cfemail="65060100250d0a1108040c094b060a08" href="/cdn-cgi/l/email-protection">[email protected]</a>',
'<a class="__cf_email__" data-cfemail="ef8e8d8caf88828e8683c18c8082" href="/cdn-cgi/l/email-protection">[email protected]</a>',
'<a class="__cf_email__" data-cfemail="6307060523040e020a0f4d000c0e" href="/cdn-cgi/l/email-protection">[email protected]</a>',
'<a class="__cf_email__" data-cfemail="91a0a3a2d1f9fee5fcf0f8fdbff2fefc" href="/cdn-cgi/l/email-protection">[email protected]</a>',
];
// 步骤 1:按域名后缀分组(提取 @ 后首个 / 或 > 前的内容,增强鲁棒性)
$emailGroups = [];
foreach ($emails as $email) {
// 使用正则安全提取邮箱地址(避免依赖固定结构)
if (preg_match('/\[email\s*protected\]([^<]+)/', $email, $matches)) {
$rawEmail = trim($matches[1]);
if (str_contains($rawEmail, '@')) {
$domain = explode('@', $rawEmail)[1] ?? '';
// 清理可能的尾部空格或标点(如 .</a>)
$domain = rtrim($domain, " \t\n\r\0\x0B>.");
if (!empty($domain)) {
$emailGroups[$domain][] = $email;
}
}
}
}
// 步骤 2:按键(域名)升序排序
ksort($emailGroups);
// 步骤 3:对每组内 HTML 字符串按字典序排序,并用 '|' 连接
$resultLines = [];
foreach ($emailGroups as $domain => $group) {
asort($group); // 确保同域名下 HTML 字符串有序(如需按邮箱名排序,可先提取再 sort)
$resultLines[] = implode('|', $group);
}
// 输出结果(每行为一个域名组)
foreach ($resultLines as $line) {
echo $line . "\n";
}
?>✅ 关键要点说明:
- 不依赖 explode('@', $email) 直接解析 HTML 字符串:因原始数据中 @ 出现在 HTML 属性值里(如 data-cfemail),直接 explode 会出错。本方案通过正则 /\[email protected\]([^<]+)/ 精准定位可见邮箱文本,再提取域名,更可靠。
- 域名清洗:使用 rtrim($domain, " \t\n\r\0\x0B>.") 移除常见 HTML 截断残留字符,避免 gmail.com</a> 类错误分组。
- 两级排序:ksort() 保证域名组间顺序(如 gmail.com 在 yahoo.com 前);asort() 保证组内 HTML 字符串顺序(若需按邮箱前缀排序,可改用 usort() 提取本地部分再比较)。
- 输出格式:每行对应一个域名组,邮箱 HTML 片段以 | 连接,符合需求示例。
? 扩展建议:若需输出为 HTML 表格或 JSON,只需将 $resultLines 数组进一步转换;如需去重,可在分组前对 $emails 调用 array_unique()。


















