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

PHP 取得字串中間子字串:get_between() 函數實作與限制分析

     編輯:PHP 綜合知識

函數實作

function get_between(string $input, string $start, string $end): string
{
    $startPos = strpos($input, $start);
    if ($startPos === false) return '';
    
    $startPos += strlen($start);
    $endPos = strpos($input, $end, $startPos);
    if ($endPos === false) return '';
    
    return substr($input, $startPos, $endPos - $startPos);
}

// 測試
$string = "www.jb51.net";
echo get_between($string, "www.", ".net"); // jb51

原版程式碼問題分析

// 原版有誤:使用負長度計算容易出錯
$substr = substr($input, strlen($start)+strpos($input, $start),
    (strlen($input) - strpos($input, $end))*(-1));
// 當 $end 在 $start 之前、或多次出現時會產生錯誤結果

關鍵限制:分隔符必須唯一

$url = "https://www.jb51.net/";
echo get_between($url, "https://", "/"); 
// 預期:www.jb51.net
// 實際:空字串(因為第一個 '/' 在 'https://' 內部)

// 原因:strpos 找到第一個 '/' 位置 5,早於 'www' 起始位置

改良版:支援指定第 N 次出現

function get_between_advanced(
    string $input, 
    string $start, 
    string $end, 
    int $startOccurrence = 1, 
    int $endOccurrence = 1
): string
{
    // 找第 N 個 $start
    $pos = -1;
    for ($i = 0; $i < $startOccurrence; $i++) {
        $pos = strpos($input, $start, $pos + 1);
        if ($pos === false) return '';
    }
    $startPos = $pos + strlen($start);
    
    // 找第 N 個 $end(從 $startPos 之後開始)
    $pos = $startPos - 1;
    for ($i = 0; $i < $endOccurrence; $i++) {
        $pos = strpos($input, $end, $pos + 1);
        if ($pos === false) return '';
    }
    $endPos = $pos;
    
    return substr($input, $startPos, $endPos - $startPos);
}

// URL 解析範例
$url = "https://api.example.com/v1/users/123/profile";
echo get_between_advanced($url, "/", "/", 3, 1); // v1
echo get_between_advanced($url, "/", "/", 4, 1); // users
echo get_between_advanced($url, "/", "/", 5, 1); // 123

正則表達式替代方案

function get_between_regex(string $input, string $start, string $end): ?string
{
    // 逃脫特殊字元
    $start = preg_quote($start, '/');
    $end = preg_quote($end, '/');
    
    // 非貪婪匹配
    if (preg_match("/{$start}(.*?){$end}/s", $input, $matches)) {
        return $matches[1];
    }
    return null;
}

// 多段擷取
$html = '
內容1
內容2
'; preg_match_all('/
(.*?)<\/div>/s', $html, $matches); print_r($matches[1]); // ['內容1', '內容2']

效能比較與選擇建議

方法速度可讀性適用場景
strpos + substr最快中固定格式、高頻呼叫、分隔符唯一
preg_match較慢高複雜模式、多段擷取、分隔符可能重複
strstr/strchr快中只需「從某字元到結尾」或「開頭到某字元」

實戰:解析標準 URL 組件

// 不要自己寫解析,用內建函數
$url = "https://user:pass@api.example.com:8080/v1/users/123?sort=name#section";
$parts = parse_url($url);
/*
Array
(
    [scheme] => https
    [host] => api.example.com
    [port] => 8080
    [user] => user
    [pass] => pass
    [path] => /v1/users/123
    [query] => sort=name
    [fragment] => section
)
*/

// 取路徑段落
$segments = explode('/', trim($parts['path'], '/'));
// ['v1', 'users', '123']
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved