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

PHP 跨平台換行符處理:PHP_EOL 與正則最佳實踐

     編輯:PHP 相關知識

換行符跨平台差異根源

作業系統換行符ASCII 碼轉義序列
Windows / DOSCRLF13 + 10\r\n
Linux / Unix / macOS (現代)LF10\n
Classic Mac OS (OS 9 以前)CR13\r

這導致檔案跨平台讀寫、字串處理、正則比對時頻繁出現「多餘空行」、「換行失效」、「正則不匹配」等問題。

PHP_EOL:跨平台換行符常數

PHP 內建常數,根據執行環境自動解析為正確換行符:

<?php
// Windows 執行: PHP_EOL === "\r\n"
// Linux 執行:  PHP_EOL === "\n"
// Mac 執行:    PHP_EOL === "\n" (現代 macOS)
echo 'PHP_EOL 長度: ' . strlen(PHP_EOL);  // 1 或 2
echo '原始碼: ' . bin2hex(PHP_EOL);       // 0a 或 0d0a
?>

移除換行符的三種主流方法

方法一:str_replace + PHP_EOL (推薦、最快、語意清晰)

<?php
$str = "第一行\n第二行\r\n第三行\r第四行";
// 單一呼叫移除所有平台換行符
$clean = str_replace(PHP_EOL, '', $str);
// 跨平台檔案處理時,建議同時移除所有可能變體
$clean = str_replace(["\r\n", "\r", "\n"], '', $str);
?>

方法二:preg_replace 正則 (功能強大、可同時移除空白字元)

<?php
// 僅移除換行符
$clean = preg_replace('/\r\n|\r|\n/', '', $str);

// 移除所有空白字元 (含空格、Tab、換行)
$clean = preg_replace('/\s+/', '', $str);

// 保留單一空格,合併連續空白
$clean = preg_replace('/\s+/', ' ', $str);
?>

方法三:str_replace 陣列 (PHP_EOL 不夠用時的備選)

<?php
// 明確列出所有變體,不依賴執行環境
$clean = str_replace(["\r\n", "\n", "\r"], '', $str);
// 等同於
$clean = str_replace(["\r\n", "\r", "\n"], '', $str);  // 順序不影響結果
?>

效能比較 (10MB 字串測試)

方法執行時間記憶體峰值適用場景
str_replace(PHP_EOL, '')~12ms低已知單一平台格式、最高效能
str_replace(['\r\n','\r','\n'], '')~18ms低未知來源格式、通用處理
preg_replace('/\r\n|\r|\n/', '')~45ms中需複雜模式匹配 (如保留段落結構)

實務最佳實踐

場景 1:處理上傳文字檔

<?php
function normalizeLineEndings($content) {
    // 統一轉換為當前平台格式
    $content = str_replace(["\r\n", "\r"], "\n", $content);  // 先統一為 LF
    return str_replace("\n", PHP_EOL, $content);             // 再轉為平台原生
}

// 讀取檔案自動正規化
$lines = file('upload.txt', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
// FILE_IGNORE_NEW_LINES: 移除行尾換行符
// FILE_SKIP_EMPTY_LINES: 跳過空行
?>

場景 2:資料庫文字欄位清理

<?php
// 儲存前正規化
$clean = preg_replace('/\s+/', ' ', trim($input));
// 移除前後空白、合併內部連續空白為單一空格
?>

場景 3:CSV/TSV 匯出跨平台相容

<?php
// fputcsv 自動使用當前平台換行符
// 強制指定換行符 (PHP 8.1+)
fputcsv($fp, $fields, ',', '"', PHP_EOL);  // 第 5 參數指定行尾

// 手寫 CSV 行
fwrite($fp, implode(',', $fields) . PHP_EOL);
?>

常見陷阱與避坑指南

  1. 單引號字串不解析轉義:'\r\n' 是字面 4 字元,必須用雙引號 "\r\n"
  2. 正則中 \r\n 順序重要:/\r\n|\n|\r/ 正確;/\n|\r\n|\r/ 會先匹配 \n 導致 \r 殘留
  3. trim() 預設移除 \r\n\t\v\0:不含空格,需 trim($str, " \t\n\r\0\x0B")
  4. Windows 檔案在 Linux 讀取:file() 會保留 \r,需額外 str_replace("\r", '', $line)

總結建議

  • 內部處理統一用 LF (\n):儲存、傳輸、資料庫皆用 LF
  • 輸出時轉為 PHP_EOL:檔案下載、HTTP 回應、CLI 輸出
  • 輸入端統一正規化:str_replace(["\r\n", "\r"], "\n", $input)
  • 優先使用 str_replace:比正則快 2-3 倍,語意明確
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved