PHP Conference Nagoya 2025

strnatcmp

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

strnatcmp"Doğal sıralama" algoritmasını kullanarak dizgeleri karşılaştırır

Açıklama

strnatcmp(string $dizge1, string $dizge2): int

Bu işlev, "doğal sıralama" adı verilen ve alfasayısal dizgeleri insanlarca yapılan sıralamaya uygun olarak sıralayan bir algoritmayı gerçekler. Karşılaştırma harf büyüklüğüne duyarlı olarak yapılır.

Bağımsız Değişkenler

dizge1

İlk dizge.

dizge2

İkinci dizge.

Dönen Değerler

dizge1 dizgesi dizge2 dizgesinden küçükse -1; dizge1 dizgesi dizge2 dizgesinden büyükse 1; dizge1 dizgesi ile dizge2 dizgesi aynıysa o döndürür.

Sürüm Bilgisi

Sürüm: Açıklama
8.2.0 Bu işlev artık -1 veya 1 döndürüyor, evvelce pozitif vaya negatif bir sayı döndürürdü.

Örnekler

Bu örnekte, bilgisiyar dizge sıralaması yapan strcmp() işlevi ile insani dizge sıralaması yapan strnatcmp() işlevinin sonuçları karşılaştırılmıştır:

<?php
$arr1
= $arr2 = array("img12.png", "img10.png", "img2.png", "img1.png");
echo
"Standart dizge karşılaştırması\n";
usort($arr1, "strcmp");
print_r($arr1);
echo
"\nDoğal dizge sıralama karşılaştırması\n";
usort($arr2, "strnatcmp");
print_r($arr2);
?>

Yukarıdaki örneğin çıktısı:

Standart dizge karşılaştırması
Array
(
    [0] => img1.png
    [1] => img10.png
    [2] => img12.png
    [3] => img2.png
)

Doğal dizge sıralama karşılaştırması
Array
(
    [0] => img1.png
    [1] => img2.png
    [2] => img10.png
    [3] => img12.png
)
Daha fazla bilgi için bakınız: Martin Pool'un » Natural Order String Comparison belgesi.

Ayrıca Bakınız

  • preg_match() - Bir düzenli ifadeyi eşleştirmeye çalışır
  • strcasecmp() - İkil olarak güvenilir ve harf büyüklüğüne duyarsız dizge karşılaştırması yapar
  • substr() - Dizgenin bir kısmını döndürür
  • stristr() - Harf büyüklüğüne duyarsız olarak ilk alt dizgeyi bulur
  • strcmp() - İkil olarak güvenilir dizge karşılaştırması yapar
  • strncmp() - İlk n karakteri ikil olarak karşılaştırır
  • strncasecmp() - İlk n karakteri ikil ve harf büyüklüğüne duyarsız olarak karşılaştırır
  • strnatcasecmp() - "Doğal sıralama" algoritmasını kullanarak dizgeleri harf büyüklüğüne duyarsız olarak karşılaştırır
  • strstr() - İlk alt dizgeyi bulur
  • natsort() - Bir diziyi "doğal sıralama" algoritmasıyla sıralar
  • natcasesort() - Bir diziyi harf büyüklüğüne duyarsız "doğal sıralama" algoritmasıyla sıralar

add a note

User Contributed Notes 4 notes

up
6
in dot games dot mq at gmail dot com
7 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']);} );
up
2
thomas at uninet dot se
18 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).

These functions might work instead.
<?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);
}
?>

The code is not optimized. It was just made to solve my problem.
up
0
chris at ocproducts dot com
7 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.
up
-3
spamspamspam at gmx dot com
6 years ago
Some more remarkable outcomes:

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

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

It's not about localisation:

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

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