處理用戶輸入、爬蟲數據、日志分析時,常需清理多餘空白字符。PHP 提供多種方式:trim、preg_replace、str_replace、PHP_EOL 常量。本文系統梳理各場景最佳實踐。
| 字符 | 轉義序列 | ASCII | 正則元字符 | 說明 |
|---|---|---|---|---|
| 空格 | | 32 | \s (包含) | 普通空格 |
| 換行符 | \n | 10 | \n, \s | Linux/Unix/macOS 現代 |
| 回車符 | \r | 13 | \r, \s | 舊 Mac OS (OS 9)、Windows 組合 |
| 換行+回車 | \r\n | 13+10 | \r\n | Windows 標準換行 |
| 製表符 | \t | 9 | \t, \s | 水平製表 |
| 垂直製表 | \v | 11 | \v, \s | 極少用 |
| 換頁符 | \f | 12 | \f, \s | 打印控制 |
\s 匹配:空格、\t、\n、\r、\v、\f。
<?php
$str = " Hello World \n\r\t ";
$clean = trim($str); // "Hello World"
?>
ltrim() 只去左,rtrim() 只去右。trim($str, " \t\n\r\0\x0B")。<?php
$str = "This has\t\tmultiple\n\nspaces";
// 方法一:正則(推薦)
$clean = preg_replace('/\s+/', ' ', $str); // "This has multiple spaces"
// 方法二:針對性替換(原文示例)
$str = trim($str);
$str = preg_replace('/\s(?=\s)/', '', $str); // 移除後面還有空白的字符
$str = preg_replace('/[\n\r\t]/', ' ', $str); // 非空格空白轉空格
?>
<?php
$str = "Line1\nLine2\r\nLine3\tTab";
// 移除所有 \s
$compact = preg_replace('/\s+/', '', $str); // "Line1Line2Line3Tab"
?>
<?php
// 方法一:str_replace 陣列(順序重要:先替換 \r\n)
$str = str_replace(["\r\n", "\r", "\n"], "\n", $str);
// 方法二:正則
$str = preg_replace('/\r\n|\r|\n/', "\n", $str);
// 方法三:使用 PHP_EOL 常量(推薦,語義清晰)
$str = str_replace(PHP_EOL, "\n", $str);
// PHP_EOL 會根據運行平台自動為 \n (Linux/Mac) 或 \r\n (Windows)
?>
<?php
function get_client_eol() {
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (stripos($ua, 'Win') !== false) return "\r\n";
if (stripos($ua, 'Mac') !== false) return "\r"; // 旧 Mac OS 9
return "\n"; // Linux/Unix/现代 Mac/iOS/Android
}
?>
注意: 現代 Web 開發中,統一內部使用 \n,輸出前根據需求轉換,不要依賴 UA 判斷(不可靠、易偽造)。
<?php
$text = "Line1\nLine2\r\nLine3";
echo nl2br($text);
// 輸出: Line1<br />\nLine2<br />\r\nLine3
// 瀏覽器渲染為換行
?>
UTF-8 中存在更多空白字符(如全形空格 U+3000、零寬空格 U+200B)。
<?php
// 移除所有 Unicode 空白字符(需 /u 修飾符)
$str = "Hello\u{3000}World\u{200B}!";
$clean = preg_replace('/\p{Zs}/u', '', $str); // \p{Zs} = 空白分隔符
// 或更廣泛
$clean = preg_replace('/\p{Cf}|\p{Z}/u', '', $str); // 格式控制字符 + 所有分隔符
?>
| 操作 | 推薦函數 | 性能 | 適用場景 |
|---|---|---|---|
| 去首尾空白 | trim() | 極快 (C 級) | 輸入驗證、字段清洗 |
| 替換固定字符 | str_replace() | 快 | 已知字符替換、換行符統一 |
| 模式匹配替換 | preg_replace() | 較慢 | 合併連續空白、Unicode 空白、複雜模式 |
| 分割字符串 | preg_split() | 中等 | 按多種分隔符分割 |
<?php
/**
* 正規化字符串空白:去首尾、合併連續空白為單空格、統一換行
* @param string $str
* @param bool $keep_newline 是否保留換行(不合併為空格)
* @return string
*/
function normalize_whitespace($str, $keep_newline = false) {
if (!is_string($str)) return '';
// 統一換行為 \n
$str = str_replace(["\r\n", "\r"], "\n", $str);
if ($keep_newline) {
// 保留換行,只合併水平空白
$str = preg_replace('/[ \t\v\f]+/', ' ', $str);
// 去除行首尾空格
$str = preg_replace('/^ +| +$/m', '', $str);
} else {
// 全合併為單空格
$str = preg_replace('/\s+/', ' ', $str);
}
return trim($str);
}
/**
* 移除所有空白字符(含 Unicode)
* @param string $str
* @return string
*/
function remove_all_whitespace($str) {
return preg_replace('/\s+/u', '', (string)$str);
}
/**
* 統一換行符為 \n
* @param string $str
* @return string
*/
function unify_newlines($str) {
return str_replace(["\r\n", "\r"], "\n", (string)$str);
}
?>
str_replace('\n', ...): 單引號下 \n 是字面字符串「反斜杠+n」,必須用雙引號 "\n" 或 PHP_EOL。/u: 處理 UTF-8 必加,否則多字節字符會被錯誤拆分匹配。PHP_EOL 只代表服務端系統換行符,不代表客戶端,寫文件用它,處理輸入別用它。\n 的文本,輸出時按前端需求轉換(nl2br、json_encode、str_replace("\n", "
"))。掌握空白字符的分類、正則元字符、PHP 內置函數特性,能精準高效地完成文本清洗、正規化、跨平台兼容等任務。原則:內部統一 \n,輸入正規化,輸出按需轉換。