PHP如何高效删除字符串中重复的域名?
- 虚拟主机
- 2025-12-16
- 7
在PHP开发中,处理字符串中的重复域名是一个常见的需求,尤其是在处理URL列表、日志分析或数据清洗时,域名重复可能由于用户输入不规范、爬虫数据重复或系统合并数据等原因产生,如果不加以处理,可能会导致数据冗余、统计偏差或性能问题,本文将详细介绍如何使用PHP从字符串中高效删除重复域名,涵盖多种实现方法、优缺点分析及代码示例,帮助开发者根据实际场景选择最合适的解决方案。
理解域名重复的常见场景
在开始编写代码前,需要明确“域名重复”的具体定义,域名通常包含协议(如http://、https://)、子域名(如www.)、主域名(如example.com)和路径(如/path/page),重复可能出现在以下层面:
- 完全重复:字符串中包含相同的完整URL,如https://www.example.com/page出现多次。
- 主域名重复:忽略协议和子域名,如http://example.com和https://www.example.com被视为重复。
- 路径差异:相同主域名但路径不同,如example.com/page1和example.com/page2是否算重复需根据需求判断。
本文以最常见的“主域名重复”为例,即忽略协议和子域名,仅保留主域名的唯一性,将https://www.example.com、http://example.com、ftp://sub.example.com统一视为example.com。

方法一:使用正则表达式提取主域名
正则表达式是处理字符串的强大工具,通过匹配URL中的主域名部分,可以实现去重,以下是实现步骤:
提取主域名的正则表达式
主域名的提取需要考虑顶级域名(如.com、.org)和二级域名(如.co.uk),可以使用以下正则表达式:
$pattern = '/^(https?://)?(?:www.)?([^/?:]+)(?:[/?:].*)?$/i';
- ^(https?://)?:匹配可选的http://或https://。
- (?:www.)?:匹配可选的www.前缀。
- ([^/?:]+):捕获主域名部分(直到遇到/、?或:)。
- (?:[/?:].*)?$:匹配可选的路径、查询参数等。
实现代码
function removeDuplicateDomains($string) { $urls = explode(' ', $string); // 假设域名以空格分隔 $uniqueDomains = []; foreach ($urls as $url) { if (preg_match('/^(https?://)?(?:www.)?([^/?:]+)(?:[/?:].*)?$/i', $url, $matches)) { $domain = strtolower($matches[2]); // 转换为小写避免大小写差异 $uniqueDomains[$domain] = $url; // 用域名作为键去重 } } return implode(' ', array_values($uniqueDomains)); } // 示例 $string = "https://www.example.com http://example.com ftp://sub.example.com"; echo removeDuplicateDomains($string); // 输出: https://www.example.com
优缺点分析
- 优点:逻辑清晰,适合处理简单URL格式。
- 缺点:正则表达式对复杂域名(如多级域名)支持有限,需手动调整规则。
方法二:使用parse_url和explode函数组合
PHP内置的parse_url函数可以解析URL的各个部分,结合explode进一步提取主域名,适合更灵活的场景。

实现代码
function removeDuplicateDomainsV2($string) { $urls = explode(' ', $string); $uniqueDomains = []; foreach ($urls as $url) { $parsed = parse_url($url); if (isset($parsed['host'])) { $host = $parsed['host']; // 移除www.前缀 $domain = preg_replace('/^www./', '', strtolower($host)); $uniqueDomains[$domain] = $url; } } return implode(' ', array_values($uniqueDomains)); } // 示例 $string = "https://www.example.com http://example.com ftp://sub.example.com"; echo removeDuplicateDomainsV2($string); // 输出: https://www.example.com
优缺点分析
- 优点:parse_url比正则更稳定,能正确处理复杂URL。
- 缺点:需额外处理www.前缀,对多级域名(如.co.uk)需进一步拆分。
方法三:使用第三方库(如Purl)
对于复杂需求,可以使用第三方库如Purl(PHP URL解析库),它提供了更强大的域名解析功能。
安装Purl
通过Composer安装:

composer require purl/purl
实现代码
require 'vendor/autoload.php'; use PurlUrl; function removeDuplicateDomainsV3($string) { $urls = explode(' ', $string); $uniqueDomains = []; foreach ($urls as $url) { try { $purl = new Url($url); $domain = $purl>host>getRegisterableDomain(); // 获取可注册域名 if ($domain) { $uniqueDomains[$domain] = $url; } } catch (Exception $e) { // 忽略无效URL } } return implode(' ', array_values($uniqueDomains)); } // 示例 $string = "https://www.example.com http://example.com ftp://sub.example.com"; echo removeDuplicateDomainsV3($string); // 输出: https://www.example.com
优缺点分析
- 优点:支持多级域名解析(如识别.co.uk为顶级域名),代码简洁。
- 缺点:需引入第三方库,增加项目依赖。
性能对比与选择建议
下表归纳了三种方法的性能和适用场景:
| 方法 | 性能 | 复杂度 | 适用场景 |
|---|---|---|---|
| 正则表达式 | 高 | 中 | 简单URL,无需多级域名支持 |
| parse_url+explode | 中 | 低 | 中等复杂度URL,需稳定解析 |
| Purl库 | 低 | 低 | 复杂域名,需多级域名支持 |
- 简单场景:选择方法一或方法二,避免引入额外依赖。
- 复杂场景:选择方法三,尤其是需要处理国际ized域名或特殊顶级域名时。
处理字符串中其他分隔符
如果域名不是以空格分隔,而是逗号、换行符等,可调整explode的参数:
$urls = preg_split('/[,;n]/', $string); // 按逗号、分号或换行分割
相关问答FAQs
问题1:如何区分主域名和子域名?
答:主域名是可注册的最高级别域名(如example.com),子域名是主域名下的前缀(如sub.example.com),可以通过以下方式区分:
- 使用Purl库的getRegisterableDomain()方法直接获取主域名。
- 手动拆分:将域名按点分割,取最后两部分(如example.com),但需处理多级域名(如co.uk)。
问题2:如何保留原始URL格式而去重?
答:在去重时,用主域名作为键存储原始URL,最后输出键对应的值即可。
$uniqueDomains[$domain] = $url; // 存储原始URL return implode(' ', array_values($uniqueDomains)); // 输出原始URL列表
这样既保证了主域名唯一性,又保留了原始URL的格式(如协议、路径等)。