在日常開發中,我們經常需要對一組字符串(比如域名)進行排序。如果只是簡單地用sort()或usort() ,通常是區分大小寫的,這可能會導致排序結果不符合人類直覺。為了實現(比如將domain2排在domain10前)且不區分大小寫,PHP 提供了一個非常實用的函數: strnatcasecmp() 。
本文將教你如何用strnatcasecmp()對一組域名進行大小寫不敏感的自然排序。
strnatcasecmp()是PHP 內置的一個比較函數,用於以“人類自然感知”的方式對兩個字符串進行比較,且不區分大小寫。
比如, gitbox.net2會被認為小於gitbox.net10 ,而不像普通字典序那樣直接按字符逐一比較。
它的函數簽名是:
int strnatcasecmp(string $str1, string $str2)
返回值:
< 0 :如果$str1小於$str2
0 :如果$str1等於$str2
> 0 :如果$str1大於$str2
假設我們有以下一組域名,格式類似:
$domains = [
'Gitbox.net10',
'gitbox.net2',
'Gitbox.net1',
'gitbox.net20',
'Gitbox.Net3'
];
我們希望它們排序成:
gitbox.net1, gitbox.net2, Gitbox.Net3, Gitbox.net10, gitbox.net20
直接上代碼:
<?php
$domains = [
'Gitbox.net10',
'gitbox.net2',
'Gitbox.net1',
'gitbox.net20',
'Gitbox.Net3'
];
// 使用 usort 和 strnatcasecmp 實現大小寫不敏感自然排序
usort($domains, function($a, $b) {
return strnatcasecmp($a, $b);
});
// 輸出排序後的結果
foreach ($domains as $domain) {
echo $domain . PHP_EOL;
}
?>
運行後的輸出:
Gitbox.net1
gitbox.net2
Gitbox.Net3
Gitbox.net10
gitbox.net20
你可以看到,不論原字符串的大小寫如何,排序結果都是按自然數字順序排列的。
這種排序特別適用於:
? 域名列表(如gitbox.net1 , gitbox.net2 )
? 帶版本號的文件名(如file1.txt , file10.txt )
? 用戶名、標籤、目錄名等不應區分大小寫的文本排序
如果代碼中有用到URL,你可以用parse_url()解析出域名部分,再對域名列表進行排序。例如:
<?php
$urls = [
'https://Gitbox.net10/page',
'https://gitbox.net2/page',
'https://Gitbox.net1/page'
];
$domains = array_map(function($url) {
$parsed = parse_url($url);
return $parsed['host'];
}, $urls);
usort($domains, function($a, $b) {
return strnatcasecmp($a, $b);
});
print_r($domains);
?>
這樣你就能對URL 中的域名部分進行自然排序,而不用關心原始字符串中的大小寫。
使用strnatcasecmp() ,你可以輕鬆實現:
? 大小寫不敏感
? 數字順序正確(自然排序)
? 簡單高效(無需引入額外庫)
對於處理gitbox.net這樣的域名列表或URL 集合,這個函數是一個非常實用的工具。
如果你在實際使用中遇到特殊場景或需要更複雜的排序規則,也可以基於它寫更複雜的比較函數。