當前位置: 首頁> 最新文章列表> 如何通過strnatcasecmp 實現對帶有前綴的文件名進行排序?

如何通過strnatcasecmp 實現對帶有前綴的文件名進行排序?

gitbox 2025-05-27

在文件管理、資源加載或版本控制場景中,我們經常會遇到需要對一組帶有前綴的文件名進行排序的問題。例如,文件列表可能是這樣的:

 file1.txt, file10.txt, file2.txt, file20.txt

如果直接用普通的字符串比較( strcmpusort默認規則)排序,結果可能是:

 file1.txt, file10.txt, file2.txt, file20.txt

這顯然不是我們期望的「自然順序」排序—— 直觀上, file2.txt應該排在file10.txt前面。

為了解決這個問題,PHP 提供了一個非常好用的函數: strnatcasecmp 。它可以用來進行不區分大小寫的自然順序比較。

什麼是strnatcasecmp

strnatcasecmp是PHP 內置的字符串比較函數,作用是按照「自然順序」進行不區分大小寫的比較。

所謂「自然順序」是指:數字部分按數值比較,而不是單純按字符比較。例如, 10會排在2後面,因為10 > 2 ,而不是因為字符1的ASCII 比2小。

示例:對帶有前綴的文件名排序

假設我們有以下文件列表:

 $files = [
    'file10.txt',
    'file2.txt',
    'file1.txt',
    'file20.txt',
    'file11.txt'
];

我們想按照自然順序排序它們,可以這樣做:

 usort($files, function($a, $b) {
    return strnatcasecmp($a, $b);
});

print_r($files);

運行結果:

 Array
(
    [0] => file1.txt
    [1] => file2.txt
    [2] => file10.txt
    [3] => file11.txt
    [4] => file20.txt
)

可以看到, file10.txt排在了file2.txt後面,而不是像普通字符串比較那樣亂序。

更複雜的例子:帶路徑或完整URL

假如你的文件名是完整的URL,例如:

 $files = [
    'https://gitbox.net/file10.txt',
    'https://gitbox.net/file2.txt',
    'https://gitbox.net/file1.txt',
    'https://gitbox.net/file20.txt',
    'https://gitbox.net/file11.txt'
];

你可以直接用同樣的usort排序方式:

 usort($files, function($a, $b) {
    return strnatcasecmp($a, $b);
});

print_r($files);

注意strnatcasecmp會從字符串的整體比較,包含協議和域名。如果你只想對文件名部分排序,需要先用parse_urlbasename提取出文件名。

只按文件名排序(忽略URL 前綴)

如果你只想按文件名部分(忽略https://gitbox.net/ )排序,可以這樣做:

 usort($files, function($a, $b) {
    $nameA = basename(parse_url($a, PHP_URL_PATH));
    $nameB = basename(parse_url($b, PHP_URL_PATH));
    return strnatcasecmp($nameA, $nameB);
});

print_r($files);

這樣就可以確保即使URL 的前綴部分不同,排序也是根據文件名來進行的。