首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 刪除文本文件重複行完整解決方案:支援大小寫忽略與自定義換行符

     編輯:PHP 相關知識

PHP 刪除文本文件重複行完整解決方案:支援大小寫忽略與自定義換行符

處理日誌去重、清單去重等場景時,需要高效刪除文本文件中的重複行。本文提供兩個通用函數:RemoveDuplicatedLines() 直接操作檔案,RemoveDuplicatedLinesByString() 處理字串,支援大小寫忽略、自定義分隔符、記憶體友善。可直接納入工具庫。

核心函數:RemoveDuplicatedLinesByString()

<?php
/**
 * 移除字串中重複的行
 *
 * @param string $lines       輸入字串
 * @param bool   $ignoreCase  是否忽略大小寫
 * @param string $newLine     行分隔符,預設 "\n"
 * @return string             去重後字串
 */
function RemoveDuplicatedLinesByString(string $lines, bool $ignoreCase = false, string $newLine = "\n"): string {
    // 陣列輸入自動轉字串
    if (is_array($lines)) {
        $lines = implode($newLine, $lines);
    }

    $lines = explode($newLine, $lines);
    $uniqueLines = [];
    $duplicateCount = 0;

    foreach ($lines as $line) {
        $currentLine = trim($line);
        if ($currentLine === '') continue; // 跳過空行

        $key = $ignoreCase ? strtolower($currentLine) : $currentLine;

        if (!isset($uniqueLines[$key])) {
            $uniqueLines[$key] = $currentLine; // 保留首次出現的原始大小寫
        } else {
            $duplicateCount++;
        }
    }

    // 可選:排序保持穩定輸出
    // ksort($uniqueLines); // 按 key 排序
    // asort($uniqueLines); // 按 value 排序

    return implode($newLine, array_values($uniqueLines));
}
?>

檔案級封裝:RemoveDuplicatedLines()

<?php
/**
 * 直接處理檔案:讀取 → 去重 → 覆寫
 *
 * @param string $filepath    檔案路徑
 * @param bool   $ignoreCase  忽略大小寫
 * @param string $newLine     行分隔符
 * @return int                移除的重複行數
 * @throws Exception          檔案不存在或不可寫
 */
function RemoveDuplicatedLines(string $filepath, bool $ignoreCase = false, string $newLine = "\n"): int {
    if (!file_exists($filepath)) {
        throw new Exception("RemoveDuplicatedLines error: File '{$filepath}' does not exist!");
    }

    $content = file_get_contents($filepath);
    if ($content === false) {
        throw new Exception("RemoveDuplicatedLines error: Cannot read file '{$filepath}'!");
    }

    $newContent = RemoveDuplicatedLinesByString($content, $ignoreCase, $newLine);
    $removedCount = substr_count($content, $newLine) - substr_count($newContent, $newLine); // 近似計算

    if (!is_writable($filepath)) {
        throw new Exception("RemoveDuplicatedLines error: File '{$filepath}' is not writable!");
    }

    $bytes = file_put_contents($filepath, $newContent);
    if ($bytes === false) {
        throw new Exception("RemoveDuplicatedLines error: Failed to write file '{$filepath}'!");
    }

    return $removedCount;
}
?>

使用範例

<?php
// 範例 1:基本去重
$removed = RemoveDuplicatedLines('data.txt');
echo "已移除 {$removed} 行重複內容\n";

// 範例 2:忽略大小寫去重 (Apple, apple 視為同一行)
RemoveDuplicatedLines('data.txt', true);

// 範例 3:自定義分隔符 (分號分隔的單行資料)
$singleLine = 'foo;bar;foo;foo;baz';
$deduped = RemoveDuplicatedLinesByString($singleLine, false, ';');
echo $deduped; // foo;bar;baz

// 範例 4:處理陣列輸入
$arr = ['line1', 'line2', 'line1', 'line3'];
echo RemoveDuplicatedLinesByString($arr); // line1\nline2\nline3
?>

效能與記憶體考量

  • 時間複雜度:O(n),單次遍歷,陣列鍵值查找 O(1)。
  • 空間複雜度:O(u),u 為唯一行數。大檔案 (GB 級) 建議改用流式處理 + 磁碟暫存 (如 sort -u 系統指令)。
  • 編碼一致性:確保檔案編碼與 PHP 腳本一致 (建議 UTF-8),避免多位元組字元截斷導致誤判。

進階:保留最後出現而非首次

<?php
function RemoveDuplicatedLinesKeepLast(string $lines, bool $ignoreCase = false, string $newLine = "\n"): string {
    $arr = is_array($lines) ? $lines : explode($newLine, $lines);
    $map = [];
    // 反向遍歷,後出現的覆蓋先出現的
    for ($i = count($arr) - 1; $i >= 0; $i--) {
        $line = trim($arr[$i]);
        if ($line === '') continue;
        $key = $ignoreCase ? strtolower($line) : $line;
        if (!isset($map[$key])) {
            $map[$key] = $line;
        }
    }
    return implode($newLine, array_reverse(array_values($map)));
}
?>

根據業務需求選擇保留首次或最後出現,工具函數靈活應對。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved