萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 字串搜尋函數完整對比:strstr、strrchr、strpos、strrpos、stripos 使用場景與效能

四大核心函數對照表

函數方向大小寫回傳值適用場景
strstr()左→右敏感子字串~結尾 (含針)提取後綴、檢查是否包含
stristr()左→右不敏感子字串~結尾不分大小寫檢查/提取
strrchr()右→左敏感最後匹配字元~結尾取副檔名、最後一段路徑
strpos()左→右敏感位置索引 (int) / false高效判斷包含、定位位置
stripos()左→右不敏感位置索引不分大小寫定位
strrpos()右→左敏感最後位置索引找最後一次出現位置

實戰範例

<?php
$text = '天高任鳥飛,海闊憑魚躍';

// strstr:從左找,回傳含針的後段
echo strstr($text, ',');     // ,海闊憑魚躍
echo strstr($text, '鳥飛');   // 鳥飛

// strrchr:從右找字元 (注意:第二參數只取首字元)
$eng = 'I have a great dream.';
echo strrchr($eng, 'e');      // eam. (最後一個 e 到結尾)
echo strrchr($eng, 've');     // veam. (只拿 'v' 做匹配!)

// strpos:高效定位位置 (必須用 !== false 判斷)
$abstract = 'I am an abstract about abroad.';
echo strpos($abstract, 'ab');   // 8 (第一個 ab)
echo strpos($abstract, 'ab', 9); // 22 (從索引 9 開始找)

// strrpos:找最後位置
$wang = 'I am is wang hui.';
echo strrpos($wang, 'I');   // 0 (大寫 I)
echo strrpos($wang, 'i');   // 15 (小寫 i 最後位置)
echo strrpos($wang, 'an');  // 5 (an 最後位置)
?>

關鍵陷阱:0 vs false

<?php
$str = 'hello world';

// ❌ 錯誤:0 會被當作 false
if (strpos($str, 'h')) { echo 'Found'; } // 不會執行!因為位置 0 是 false

// ✅ 正確:嚴格比較
if (strpos($str, 'h') !== false) { echo 'Found at 0'; }

// ✅ PHP 8.0+ 新函數:更直觀
if (str_contains($str, 'h')) { echo 'Contains'; }      // 包含檢查
if (str_starts_with($str, 'he')) { echo 'Starts with'; } // 開頭檢查
if (str_ends_with($str, 'ld')) { echo 'Ends with'; }   // 結尾檢查
?>

效能對比

<?php
$haystack = str_repeat('abcdefghijklmnopqrstuvwxyz ', 10000); // ~270KB
$needle = 'xyz';

$iterations = 1000;

$start = hrtime(true);
for ($i=0; $i<$iterations; $i++) strpos($haystack, $needle);
echo "strpos: " . (hrtime(true)-$start)/1e6/$iterations . " ms\n";

$start = hrtime(true);
for ($i=0; $i<$iterations; $i++) strstr($haystack, $needle);
echo "strstr: " . (hrtime(true)-$start)/1e6/$iterations . " ms\n";

$start = hrtime(true);
for ($i=0; $i<$iterations; $i++) preg_match('/' . $needle . '/', $haystack);
echo "preg_match: " . (hrtime(true)-$start)/1e6/$iterations . " ms\n";

/* 典型輸出:
strpos:     0.012 ms
strstr:     0.018 ms
preg_match: 0.085 ms
結論:單純查找用 strpos/stripos 最快,需提取子串用 strstr,複雜模式才用正則
*/
?>

多位元組字串 (中文) 處理

<?php
$zh = '天高任鳥飛,海闊憑魚躍';

// 必須用 mb_* 系列,指定編碼
echo mb_strpos($zh, '鳥');      // 6 (字元索引,非位元組)
echo mb_strrpos($zh, '海');     // 9
echo mb_strstr($zh, '海');      // 海闊憑魚躍
echo mb_substr($zh, 4, 3);      // 鳥飛,

// 內部編碼設定 (影響所有 mb_* 函數)
mb_internal_encoding('UTF-8');
?>

最佳實踐選擇指南

  1. 只需判斷是否包含:str_contains() (PHP 8.0+) 或 strpos() !== false
  2. 需提取匹配後內容:strstr() / mb_strstr()
  3. 需提取匹配前內容:strstr($hay, $needle, true) (PHP 5.3+)
  4. 找最後一次出現:strrpos() / strripos()
  5. 取副檔名/最後路徑段:pathinfo($path, PATHINFO_EXTENSION) 或 basename() 優於 strrchr()
  6. 中文/多語言:全程使用 mb_* 系列,設定 mb_internal_encoding('UTF-8')
copyright © 萬盛學電腦網 all rights reserved