PHP 8.1.2 Released!

strnatcmp

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

strnatcmpСравнение строк с использованием алгоритма "natural order"

Описание

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

Эта функция реализует алгоритм сравнения, упорядочивающий алфавитно-цифровые строки подобно тому, как это сделал бы человек, такой алгоритм называется "natural ordering". Сравнение происходит с учётом регистра.

string1

Первая строка.

string2

Вторая строка.

Возвращаемые значения

Подобно другим функциям сравнения строк, данная функция возвращает отрицательное число, если string1 меньше, чем string2, положительное число, если string1 больше, чем string2, и 0 если строки равны.

Примеры

Пример, показывающий отличие этого алгоритма от обычных функций сравнения (используемых в strcmp()), приведён ниже:

<?php
\$arr1
\$arr2 = array("img12.png""img10.png""img2.png""img1.png");
echo
"Стандартный алгоритм сравнения\n";
usort(\$arr1"strcmp");
print_r(\$arr1);
echo
"\nАлгоритм \"natural order\"\n";
usort(\$arr2"strnatcmp");
print_r(\$arr2);
?>

Результат выполнения данного примера:

Стандартный алгоритм сравнения
Array
(
 => img1.png
 => img10.png
 => img12.png
 => img2.png
)

Алгоритм "natural order"
Array
(
 => img1.png
 => img2.png
 => img10.png
 => img12.png
)
Для получения дополнительной информации смотрите » Natural Order String Comparison.

Смотрите также

• preg_match() - Выполняет проверку на соответствие регулярному выражению
• strcasecmp() - Бинарно-безопасное сравнение строк без учёта регистра
• substr() - Возвращает подстроку
• stristr() - Регистронезависимый вариант функции strstr
• strcmp() - Бинарно-безопасное сравнение строк
• strncmp() - Бинарно-безопасное сравнение первых n символов строк
• strncasecmp() - Бинарно-безопасное сравнение первых n символов строк без учёта регистра
• strnatcasecmp() - Сравнение строк без учёта регистра с использованием алгоритма "natural order"
• strstr() - Находит первое вхождение подстроки
• natsort() - Сортирует массив, используя алгоритм "natural order"
• natcasesort() - Сортирует массив, используя алгоритм "natural order" без учёта регистра символов

in dot games dot mq at gmail dot com
5 years ago
Can also be used with combination of a compare for an array nested value, like

<?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
15 years ago
There seems to be a bug in the localization for strnatcmp and strnatcasecmp. I searched the reported bugs and found a few entries which were up to four years old (but the problem still exists when using swedish characters).

<?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;

\$left = \$lMatch;
} else {

\$lTest = \$left;

\$left = '';
}
if(
preg_match('/^([^0-9]*)([0-9].*)\$/Us', \$right, \$rMatch)) {

\$rTest = \$rMatch;

\$right = \$rMatch;
} 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);

\$left = \$lMatch;
} else {

\$lTest = 0;
}
if(
preg_match('/^([0-9]+)([^0-9].*)?\$/Us', \$right, \$rMatch)) {

\$rTest = intval(\$rMatch);

\$right = \$rMatch;
} else {

\$rTest = 0;
}

\$test = \$lTest - \$rTest;
if(
\$test != 0) {
return
\$test;
}
}
return
strcmp(\$left, \$right);
}
?>

The code is not optimized. It was just made to solve my problem.
-1
chris at ocproducts dot com
4 years ago
This function has some interesting behaviour on strings consisting of mixed numbers and letters.

One may expect that such a mixed string would be treated as alpha-numeric, but that is not true.

var_dump(strnatcmp('23','123')); →
int(-1)
As expected, 23<123   (even though first digit is higher, overall number is smaller)

var_dump(strnatcmp('yz','xyz')); →
int(1)
As expected, yz>xyz   (string comparison, irregardless of string length)

var_dump(strnatcmp('2x','12y')); →
int(-1)
Remarkable, 2x<12y    (does a numeric comparison)

var_dump(strnatcmp('20x','12y'));
int(1)
Remarkable, 20x>12y    (does a numeric comparison)

It seems to be splitting what is being compared into runs of numbers and letters, and then comparing each run in isolation, until it has an ordering difference.
-3
spamspamspam at gmx dot com
3 years ago
Some more remarkable outcomes:

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)
-59
Zero
11 years ago
If you want to compare \$_SESSION variables to a string use this

<?php
if(isset(\$_SESSION['usertype']))
{
echo
"usertype " .\$_SESSION['usertype'];

\$ut = \$_SESSION['usertype'];

if( 