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

PHP substr_replace() 進階應用:字串截斷省略、金額格式化、模板佔位符替換

     編輯:PHP 相關知識

`substr_replace()` 可在指定位置替換字串片段,支援正負索引、長度控制,適合**截斷過長字串加省略號**、**金額加千分位**、**模板標記替換**等場景。

語法回顧

substr_replace(string $string, string $replace, int $offset, int $length = strlen($string)): string
  • `offset > 0`:從開頭第 `offset` 字元開始 (0 索引)。
  • `offset < 0`:從結尾倒數第 `abs(offset)` 字元開始。
  • `length > 0`:替換 `length` 個字元。
  • `length < 0`:保留結尾 `abs(length)` 字元,中間替換。
  • `length = 0`:**插入**而非替換。

範例 1:過長字串保留首尾 + 省略號

<?php
function truncateMiddle(string $str, int $maxLen = 50, string $ellipsis = '...'): string {
    $len = mb_strlen($str, 'UTF-8');
    if ($len <= $maxLen) return $str;

    $keep = $maxLen - mb_strlen($ellipsis);
    $start = (int)($keep / 2);           // 前半保留
    $endKeep = $keep - $start;           // 後半保留

    $first  = mb_substr($str, 0, $start, 'UTF-8');
    $last   = mb_substr($str, -$endKeep, null, 'UTF-8');

    // 計算位元組偏移 (substr_replace 操作位元組)
    $firstBytes = mb_strlen($first, '8bit');
    $lastBytes  = mb_strlen($last, '8bit');
    $totalBytes = mb_strlen($str, '8bit');
    $replaceLen = $totalBytes - $firstBytes - $lastBytes;

    return substr_replace($str, $ellipsis, $firstBytes, $replaceLen);
}

$long = 'abcdefghijklmnopqrstuvwxyz0123456789z.jpg';
echo truncateMiddle($long, 25); // abcdefghijk...456789z.jpg
?>

範例 2:超長文字截斷於單詞邊界 + 省略號

<?php
function truncateWords(string $text, int $maxLen, string $ellipsis = '...'): string {
    $text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
    if (mb_strlen($text, 'UTF-8') <= $maxLen) return $text;

    // 先粗略截斷
    $text = mb_substr($text, 0, $maxLen, 'UTF-8');
    // 回退到最後一個空白
    $lastSpace = mb_strrpos($text, ' ', null, 'UTF-8');
    if ($lastSpace !== false) {
        $text = mb_substr($text, 0, $lastSpace, 'UTF-8');
    }
    // 移除結尾標點
    $text = rtrim($text, ".,;:!?。,、;:!?");
    return $text . $ellipsis;
}

$txt = 'welcome to bkjia, welcome to bkjia, welcome to bkjia';
echo truncateWords($txt, 35); // welcome to bkjia, welcome to...
?>

範例 3:金額加千分位分隔符 (從右往左每 3 位插入逗號)

<?php
function numberFormatComma(string $num): string {
    // 處理小數部分
    if (($pos = strpos($num, '.')) !== false) {
        $intPart = substr($num, 0, $pos);
        $decPart = substr($num, $pos);
    } else {
        $intPart = $num;
        $decPart = '';
    }

    // 從右往左插入
    $len = strlen($intPart);
    for ($i = $len - 3; $i > 0; $i -= 3) {
        $intPart = substr_replace($intPart, ',', $i, 0);
    }
    return $intPart . $decPart;
}

echo numberFormatComma('163000');      // 163,000
echo numberFormatComma('1234567.89');  // 1,234,567.89
// 實際專案建議用 number_format() 或 NumberFormatter
?>

範例 4:模板佔位符替換 (簡易版)

<?php
function renderTemplate(string $tpl, array $data): string {
    foreach ($data as $key => $val) {
        $placeholder = '{{' . $key . '}}';
        $pos = 0;
        while (($pos = strpos($tpl, $placeholder, $pos)) !== false) {
            $tpl = substr_replace($tpl, $val, $pos, strlen($placeholder));
            $pos += strlen($val); // 移至替換內容後,避免重複掃描
        }
    }
    return $tpl;
}

$tpl = 'Hello {{name}}, your order {{order_id}} is {{status}}.';
$data = ['name' => 'John', 'order_id' => '20240101001', 'status' => 'shipped'];
echo renderTemplate($tpl, $data);
// Hello John, your order 20240101001 is shipped.
?>

效能與編碼注意

議題說明對策
多字元字串 (UTF-8)`substr_replace` 操作**位元組**,中文會導致亂碼配合 `mb_substr` 計算位元組偏移,或改用 `mbstring` 系列函式
大量替換每次呼叫複製整字串,記憶體峰值高收集替換位置最後一次處理、或用 `strtr` (單次掃描)
負數 offset/length從結尾計算,直觀但易誤解註解清楚、單元測試覆蓋邊界

內建替代方案

  • 截斷省略:`mb_strimwidth($str, 0, 25, '...')` (PHP 4.0.6+)。
  • 金額格式化:`number_format($num, 2, '.', ',')` 或 `NumberFormatter::create('zh_TW', NumberFormatter::CURRENCY)`。
  • 模板引擎:Twig、Blade、Plates、Latte (安全、快取、繼承、沙箱)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved