
本文介绍一种基于词序标准化的 PHP 文本去重方案:将每行句子拆分为单词、按字母序排序后重组,再执行常规去重,从而识别并合并“单词相同但顺序不同”的语义重复行。
本文介绍一种基于词序标准化的 PHP 文本去重方案:将每行句子拆分为单词、按字母序排序后重组,再执行常规去重,从而识别并合并“单词相同但顺序不同”的语义重复行。
在处理关键词列表、搜索日志或用户输入短语等文本数据时,常遇到语义重复但字面不同的情况——例如 beef bbq recipe、bbq recipe beef 和 recipe bbq beef 实质表达相同意图,但传统 array_unique() 无法识别。其根本原因在于原生去重仅比对完整字符串,而非语义单元(即单词集合)。
解决思路是标准化每行的词序:先分词 → 排序 → 合并为规范字符串,使语义相同的行映射为完全一致的字符串,再调用 array_unique() 即可精准去重。
以下是完整、健壮的实现代码:
<?php // 读取原始文件(自动保留换行符,需后续处理)
$lines = file('input.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// 步骤1:对每一行进行语义标准化
$normalized = array_map(function($line) {
// 去首尾空白,按空格分割(注意:如含标点需先清洗)
$words = explode(' ', trim($line));
// 过滤空单词(防多个连续空格导致空元素)
$words = array_filter($words, function($w) { return $w !== ''; });
// 字母序升序排序(区分大小写;如需忽略大小写,可用 natcasesort 或 strtolower 预处理)
sort($words);
// 重新拼接为标准格式(单词间单空格)
return implode(' ', $words);
}, $lines);
// 步骤2:去重(基于标准化后的字符串)
$uniqueNormalized = array_unique($normalized);
// 步骤3:还原为原始语义可读形式(可选:取原始行中首次出现的版本)
// 此处为简化,直接输出标准化结果;若需保留原始格式,请见下方进阶说明
$outputLines = array_values($uniqueNormalized); // 重置数组键
file_put_contents('output.txt', implode("\n", $outputLines) . "\n");
?>
✅ 关键特性说明:
- 使用 FILE_IGNORE_NEW_LINES 避免换行符干扰分词;
- array_filter() 清除因多余空格产生的空元素;
- sort() 确保大小写敏感排序(如需统一小写,可在 explode 后添加 array_map('strtolower', $words));
- 输出末尾追加 "\n" 保证文件以换行结尾,符合 Unix/Linux 文本规范。
⚠️ 注意事项:
- 该方法假设单词以空格分隔且不含标点符号。若原始数据含逗号、句点等(如 "beef, bbq, recipe"),需先用 preg_replace('/[^\w\s]/u', '', $line) 清洗;
- 若需保留原始行格式(如首字母大写、特殊符号),应建立标准化字符串 → 原始行的映射关系,去重时优先保留首次出现的原始行;
- 对于超大文件(>100MB),建议改用流式处理(fopen + 逐行读取 + 哈希缓存),避免内存溢出。
通过词序归一化这一轻量级语义处理策略,我们突破了字符串精确匹配的局限,在不引入 NLP 库的前提下,高效实现了关键词级语义去重——兼顾准确性、可读性与工程实用性。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











