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

PHP 字串函式深度解析:strstr、strrchr、strtr 實戰用法與多位元組支援

     編輯:PHP 相關知識

PHP 字串函式深度解析:strstr、strrchr、strtr 實戰用法與多位元組支援

字串處理是 PHP 開發高頻操作。strstr、strrchr、strtr 三個函式雖然名稱相似,但用途截然不同。本文系統解析其語法、行為差異、多位元組 (mbstring) 對應版本、實戰陷阱與最佳實踐。

1. strstr / stristr:尋找首次出現並返回剩餘部分

// 語法
strstr(string $haystack, string $needle, bool $before_needle = false): string|false

// 核心行為
$email = 'user@example.com';
echo strstr($email, '@');       // @example.com (預設返回 needle 及其後)
echo strstr($email, '@', true); // user         (PHP 5.3+ $before_needle=true 返回 needle 前)

// 大小寫不敏感版本
echo stristr($email, 'EXAMPLE'); // @example.com

// 多位元組安全版本 (需 mbstring 擴展)
$zh = '你好世界,PHP';
echo mb_strstr($zh, '世界', false, 'UTF-8'); // 世界,PHP
echo mb_strstr($zh, '世界', true, 'UTF-8');  // 你好

// 關鍵點
// - 返回 false 若未找到 (嚴格比較 === false)
// - 二進制安全,可處理 \0
// - 僅搜尋字串,若 needle 為整數則視為字元 ASCII 碼 (不推薦,易混淆)
// - 效能:若僅需判斷是否存在,用 strpos() 更快、更省記憶體

2. strrchr:尋找最後一次出現並返回剩餘部分

// 語法
strrchr(string $haystack, string $needle): string|false

// 核心差異:從右向左搜尋
$path = '/var/www/html/index.php';
echo strrchr($path, '/'); // /index.php (最後一個 / 及其後)

// 多位元組版本
echo mb_strrchr($zh, '界', false, 'UTF-8'); // 界,PHP
echo mb_strrchr($zh, '界', true, 'UTF-8');  // 你好世

// 常見用途:獲取副檔名
function getExtension(string $filename): string {
    $ext = strrchr($filename, '.');
    return $ext ? substr($ext, 1) : '';
}
echo getExtension('archive.tar.gz'); // gz (只取最後一個 . 後)

3. strtr:字元/子串轉換 (高效、不覆蓋)

// 兩種呼叫模式

// 模式一:字元對字元映射 (長度必須相等)
echo strtr('Hilla Warld', 'ia', 'eo'); // Hello World
// 'i'->'e', 'a'->'o',逐字元替換,不會產生鏈式替換問題

// 模式二:關聯陣列映射 (子串替換,支援不同長度,長者優先)
$trans = [
    'Hello' => 'Hi',
    'world' => 'earth',
    'Hi'    => 'Hey', // 不會被上一條 'Hello'->'Hi' 影響,因 strtr 掃描一次完成
];
echo strtr('Hello world', $trans); // Hi earth

// 關鍵特性:單次掃描、無重疊替換、長子串優先
// 對比 str_replace:str_replace 循序執行,可能產生鏈式替換
$arr = ['a' => 'b', 'b' => 'c'];
echo str_replace(array_keys($arr), array_values($arr), 'a'); // c (a->b->c)
echo strtr('a', $arr); // b (單次掃描,a 直接變 b)

// 多位元組支援:strtr 本身支援多位元組字串 (按位元組操作但 UTF-8 相容)
// 複雜多位元組替換建議用 mb_ereg_replace / preg_replace (u 修飾符)

實戰對比表

函式用途搜尋方向返回值多位元組版本典型場景
strstr首次出現後段左→右子串/falsemb_strstrEmail 域名提取、前綴判斷
stristr不分大小寫 strstr左→右子串/false無 (用 mb_stristr 或 mb_strtolower+mb_strstr)關鍵字過濾
strrchr最後一次出現後段右→左子串/falsemb_strrchr副檔名、路徑檔名分離
strtr字元/子串映射替換單次掃描新字串原生支援模板引擎、字元正規化、編碼轉換
str_replace子串替換 (循序)左→右循序新字串/計數原生支援簡單替換、批次關鍵字替換

常見陷阱與避坑指南

  1. strstr 返回值為 0 或空字串時:必須用 === false 判斷失敗,if (strstr(...)) 會誤判 "0" 為失敗。
  2. strtr 陣列模式鍵值長度不一:長鍵優先匹配,但若鍵之間有包含關係 (如 'a' 和 'ab'),行為取決於掃描順序,建議鍵長度降序排列。
  3. 大小寫轉換陷阱:strtolower('İ') (土耳其語點式 I) 在預設 locale 下異常,多語言環境必須用 mb_strtolower($str, 'UTF-8')。
  4. 效能誤區:strtr 陣列模式對大量替換 (數萬對) 效能遠優於 str_replace,但對少量替換 str_replace 更快 (C 層優化)。

現代最佳實踐

  • 統一使用 mbstring 版本:專案啟用 mbstring.func_overload (PHP 8.2 已移除) 或手動調用 mb_strpos、mb_substr 等,確保 UTF-8 正確性。
  • 複雜模式用正則:preg_replace('/pattern/u', $replacement, $subject) 支援 Unicode 屬性、前瞻後顧、回調函式。
  • 模板引擎用專用庫:league/plates、twig/twig、bladeone,而非手寫 strtr。
  • 路徑/URL 操作用專用類:pathinfo()、parse_url()、SplFileInfo、League\Uri。

理解字串函式的語義邊界、編碼敏感度、效能特徵,是寫出正確、高效、可維護 PHP 代碼的基本功。

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