在日常开发中,我们经常需要对一组字符串(比如域名)进行排序。如果只是简单地用 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 集合,这个函数是一个非常实用的工具。
如果你在实际使用中遇到特殊场景或需要更复杂的排序规则,也可以基于它写更复杂的比较函数。