
本文介绍一种基于词序标准化的 php 文本去重方案:将每行句子拆分为单词、排序后重组,再执行唯一性过滤,从而将“beef bbq recipe”“bbq recipe beef”等语义重复但词序不同的行视为同一项并去重。
本文介绍一种基于词序标准化的 php 文本去重方案:将每行句子拆分为单词、排序后重组,再执行唯一性过滤,从而将“beef bbq recipe”“bbq recipe beef”等语义重复但词序不同的行视为同一项并去重。
在处理关键词列表、SEO 词库或用户输入的短语数据时,常遇到“内容相同但词序不同”的伪重复问题。例如 beef bbq recipe、bbq recipe beef 和 recipe bbq beef 实质表达相同语义,但传统 array_unique() 仅做字符串精确匹配,无法识别这类逻辑重复。
要实现语义级去重,核心思路是:将每行转换为标准化的“词序指纹”——即对单词进行规范化(如转小写、去除标点)、排序、合并,使语义一致的句子生成完全相同的中间表示,再统一去重。
以下是完整、健壮的 PHP 实现:
<?php // 读取原始文件(自动处理换行符)
$lines = file('input.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// 步骤1:生成标准化指纹(忽略大小写 + 单词排序)
$normalized = array_map(function($line) {
// 去除首尾空白,转小写,按空格分割
$words = preg_split('/\s+/', trim(strtolower($line)), -1, PREG_SPLIT_NO_EMPTY);
// 字母顺序排序(稳定且语言无关)
sort($words, SORT_STRING);
return implode(' ', $words);
}, $lines);
// 步骤2:去重(保留首次出现的原始行对应关系)
$uniqueNormalized = array_unique($normalized);
// 构建映射:标准化指纹 → 原始首行(可选:保留原始格式)
$originalMap = [];
foreach ($lines as $index => $original) {
$fingerprint = $normalized[$index];
if (!isset($originalMap[$fingerprint])) {
$originalMap[$fingerprint] = $original;
}
}
// 步骤3:按原始输入顺序输出去重结果(或按指纹顺序)
$resultLines = array_values($originalMap);
file_put_contents('output.txt', implode("\n", $resultLines) . "\n");
?>
✅ 关键优化说明:
- 使用 FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES 避免空行和换行符干扰;
- strtolower() 统一大小写,提升语义一致性(如 BBQ 和 bbq 视为相同);
- preg_split('/\s+/', ..., PREG_SPLIT_NO_EMPTY) 更鲁棒地处理多空格、制表符等;
- 通过 $originalMap 映射确保输出保留原始格式(非排序后的指纹),符合业务预期;
- 结尾追加 \n 保证输出文件每行以换行符结尾,符合 Unix/Linux 标准。
⚠️ 注意事项:
- 该方法适用于单词级语义等价场景,不适用于含语法结构(如否定、时态)或同义词(如 fast/quick)的深层语义去重;
- 若需支持中文分词,需替换 explode 为专业分词库(如 jieba-php);
- 大文件处理建议改用流式读取(fgets)避免内存溢出。
此方案平衡了准确性、可读性与性能,是关键词清洗、爬虫去重、推荐系统预处理中的实用技术范式。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











