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

PHP 精確移除字串首尾特定子字串:避開 trim 陷阱,採用 strpos + substr 方案

     編輯:PHP 綜合知識

常見需求:移除字串開頭的 akmumu/ 與結尾的 .json,保留中間實際路徑 /writedb。直接使用 ltrim()/rtrim() 會踩中「字元清單模式」陷阱,導致過度截斷。本文說明陷阱成因,提供安全、語意精確的解法。

陷阱重現

$str = 'akmumu/writedbsojn.json';

// 錯誤做法:trim 視參數為「字元清單」,而非「子字串」
$r = rtrim($str, '.json');  // 結果:'akmumu/writedbso'  (把 n、s、o、j 都當作可移除字元)
$l = ltrim($r, 'akmumu/');  // 結果:'writedbso'       (把 a、k、m、u、/ 都移除)

trim($str, $charlist) 會移除「出現在 charlist 中的任意字元」,直到遇到不在清單內的字元為止,不保證順序、不匹配整體子字串。

正確解法:strpos 確認 + substr 截取

<?php
$str = 'akmumu/writedb.json';

$prefix = 'akmumu/';
$suffix = '.json';

// 1. 移除前綴
if (strpos($str, $prefix) === 0) {          // 嚴格判斷「開頭就是」
    $str = substr($str, strlen($prefix));   // 截掉前綴長度
}

// 2. 移除後綴
$suffixLen = strlen($suffix);
if (strlen($str) >= $suffixLen && substr($str, -$suffixLen) === $suffix) {
    $str = substr($str, 0, -$suffixLen);    // 截掉後綴長度
}

echo $str; // 輸出:/writedb

封裝成通用函式

/**
 * 移除字串開頭的特定前綴
 */
function remove_prefix(string $str, string $prefix): string
{
    if ($prefix !== '' && strpos($str, $prefix) === 0) {
        return substr($str, strlen($prefix));
    }
    return $str;
}

/**
 * 移除字串結尾的特定後綴
 */
function remove_suffix(string $str, string $suffix): string
{
    $len = strlen($suffix);
    if ($len > 0 && strlen($str) >= $len && substr($str, -$len) === $suffix) {
        return substr($str, 0, -$len);
    }
    return $str;
}

/**
 * 同時移除前後綴
 */
function trim_affix(string $str, string $prefix = '', string $suffix = ''): string
{
    $str = remove_prefix($str, $prefix);
    $str = remove_suffix($str, $suffix);
    return $str;
}

// 使用範例
$path = 'akmumu/writedbsojn.json';
echo trim_affix($path, 'akmumu/', '.json'); // /writedbsojn

// 多層路徑範例
$url = 'https://example.com/api/v1/users.json';
echo trim_affix($url, 'https://example.com', '.json'); // /api/v1/users

進階:正則表達式替代方案

// 移除開頭固定前綴
$str = preg_replace('/^' . preg_quote('akmumu/', '/') . '/', '', $str);

// 移除結尾固定後綴
$str = preg_replace('/' . preg_quote('.json', '/') . '$/', '', $str);

// 一次完成
$str = preg_replace(
    ['/^' . preg_quote('akmumu/', '/') . '/', '/' . preg_quote('.json', '/') . '$/'],
    '',
    $str
);

正則優點:可處理複雜模式(如可選前綴、多種後綴)。缺點:效能較低、可讀性稍差。

PHP 8.0+ 新函式(若環境允許)

// PHP 8.0+ 才有
$str = 'akmumu/writedb.json';
$str = str_starts_with($str, 'akmumu/') ? substr($str, 7) : $str;
$str = str_ends_with($str, '.json') ? substr($str, 0, -5) : $str;

str_starts_with()/str_ends_with() 語意清晰、效能佳,建議 PHP 8+ 專案優先使用。

總結對照

方法適用場景優點缺點
trim/ltrim/rtrim移除首尾單一字元集合(空白、換行、特定符號)內建、快速不支援子字串匹配,易誤用
strpos + substr精確移除固定前綴/後綴子字串語意精確、相容所有 PHP 版本程式碼較冗長
preg_replace模式化前綴/後綴(可選、多選一)彈性強效能較差、需注意跳脫
str_starts_with/str_ends_withPHP 8.0+ 環境,精確判斷開頭/結尾語意明確、可讀性最佳需 PHP 8.0+
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved