strnatcmp

(PHP 4, PHP 5, PHP 7, PHP 8)

strnatcmp使用“自然顺序”算法进行字符串比较

描述

strnatcmp(string $string1, string $string2): int

此函数实现了一个比较算法,该算法以人类的方式对字母数字字符串进行排序,这被称为“自然排序”。请注意,此比较区分大小写。

参数

string1

第一个字符串。

string2

第二个字符串。

返回值

与其他字符串比较函数类似,如果 string1 小于 string2,则此函数返回 -1;如果 string1 大于 string2,则返回 1;如果它们相等,则返回 0

变更日志

版本 描述
8.2.0 此函数现在返回 -11,而以前返回负数或正数。

示例

以下示例展示了此算法与常规计算机字符串排序算法(在 strcmp() 中使用)之间的区别

<?php
$arr1
= $arr2 = array("img12.png", "img10.png", "img2.png", "img1.png");
echo
"标准字符串比较\n";
usort($arr1, "strcmp");
print_r($arr1);
echo
"\n自然顺序字符串比较\n";
usort($arr2, "strnatcmp");
print_r($arr2);
?>

以上示例将输出

Standard string comparison
Array
(
    [0] => img1.png
    [1] => img10.png
    [2] => img12.png
    [3] => img2.png
)

Natural order string comparison
Array
(
    [0] => img1.png
    [1] => img2.png
    [2] => img10.png
    [3] => img12.png
)
有关更多信息,请参见:Martin Pool 的 » 自然顺序字符串比较 页面。

参见

  • preg_match() - 执行正则表达式匹配
  • strcasecmp() - 二进制安全不区分大小写的字符串比较
  • substr() - 返回字符串的一部分
  • stristr() - 不区分大小写的 strstr
  • strcmp() - 二进制安全字符串比较
  • strncmp() - 前 n 个字符的二进制安全字符串比较
  • strncasecmp() - 前 n 个字符的二进制安全不区分大小写的字符串比较
  • strnatcasecmp() - 使用“自然顺序”算法进行不区分大小写的字符串比较
  • strstr() - 查找字符串的第一次出现
  • natsort() - 使用“自然顺序”算法对数组进行排序
  • natcasesort() - 使用不区分大小写的“自然顺序”算法对数组进行排序

添加注释

用户贡献注释 4 个注释

in dot games dot mq at gmail dot com
7 年前
也可以与数组嵌套值的比较组合使用,例如

<?php
$array
= array(
"city" => "xyz",
"names" => array(
array(
"name" => "Ana2",
"id" => 1
) ,
array(
"name" => "Ana1",
"id" => 2
)
)
);
usort($array["names"], function ($a, $b) { return strnatcmp($a['name'], $b['name']);} );
thomas at uninet dot se
18 年前
strnatcmp 和 strnatcasecmp 的本地化似乎存在错误。我搜索了已报告的错误,发现了一些已有四年的条目(但在使用瑞典字符时问题仍然存在)。

这些函数可能可以替代。
<?php
function _strnatcasecmp($left, $right) {
return
_strnatcmp(strtolower($left), strtolower($right));
}

function
_strnatcmp($left, $right) {
while((
strlen($left) > 0) && (strlen($right) > 0)) {
if(
preg_match('/^([^0-9]*)([0-9].*)$/Us', $left, $lMatch)) {
$lTest = $lMatch[1];
$left = $lMatch[2];
} else {
$lTest = $left;
$left = '';
}
if(
preg_match('/^([^0-9]*)([0-9].*)$/Us', $right, $rMatch)) {
$rTest = $rMatch[1];
$right = $rMatch[2];
} else {
$rTest = $right;
$right = '';
}
$test = strcmp($lTest, $rTest);
if(
$test != 0) {
return
$test;
}
if(
preg_match('/^([0-9]+)([^0-9].*)?$/Us', $left, $lMatch)) {
$lTest = intval($lMatch[1]);
$left = $lMatch[2];
} else {
$lTest = 0;
}
if(
preg_match('/^([0-9]+)([^0-9].*)?$/Us', $right, $rMatch)) {
$rTest = intval($rMatch[1]);
$right = $rMatch[2];
} else {
$rTest = 0;
}
$test = $lTest - $rTest;
if(
$test != 0) {
return
$test;
}
}
return
strcmp($left, $right);
}
?>

该代码没有优化,它只是为了解决我的问题而创建的。
chris at ocproducts dot com
7 年前
这个函数对由数字和字母混合组成的字符串有一些有趣的行为。

人们可能期望这样的混合字符串被视为字母数字,但事实并非如此。

var_dump(strnatcmp('23','123')); →
int(-1)
正如预期的那样,23<123(即使第一个数字更大,但总的数字更小)

var_dump(strnatcmp('yz','xyz')); →
int(1)
正如预期的那样,yz>xyz(字符串比较,不考虑字符串长度)

var_dump(strnatcmp('2x','12y')); →
int(-1)
值得注意的是,2x<12y(进行数字比较)

var_dump(strnatcmp('20x','12y'));
int(1)
值得注意的是,20x>12y(进行数字比较)

它似乎将要比较的内容拆分为数字和字母的运行,然后分别比较每个运行,直到它具有排序差异。
spamspamspam at gmx dot com
5年前
一些更值得注意的结果

var_dump(strnatcmp("0.15m", "0.2m"));
int(1)

var_dump(strnatcmp("0.15m", "0.20m"));
int(-1)

它不是关于本地化

var_dump(strnatcmp("0,15m", "0,2m"));
int(1)

var_dump(strnatcmp("0,15m", "0,20m"));
int(-1)
To Top