Как сортировать строки в естественном порядке в PHP
Функция natsort() в PHP сортирует массив в естественном порядке, treating embedded numbers as numeric values and preserving keys.
Когда вы сортируете строки, содержащие числа в PHP, стандартная алфавитная сортировка нередко даёт результат, который кажется «неправильным» для человека. Функция PHP natsort() решает эту проблему, сортируя массив с помощью алгоритма естественного порядка — так же, как человек упорядочил бы file1, file2, file10 вместо file1, file10, file2.
На этой странице рассматривается, что такое сортировка в естественном порядке, как работает natsort() (включая сохранение ключей), чем она отличается от sort(), как обрабатывать регистр и каковы типичные подводные камни.
Что такое сортировка в естественном порядке?
Сортировка в естественном порядке (также называемая алфавитно-цифровой) рассматривает последовательности цифр внутри строки как единое число, а не как отдельные символы. При обычной алфавитной сортировке "100" стоит перед "2", потому что сравнение останавливается на первом символе, а '1' меньше '2' в таблице ASCII. Сортировка в естественном порядке сравнивает 100 и 2 как числа, поэтому 2 правильно оказывается первым.
Это важно всегда, когда в строках смешаны текст и числа: имена файлов (img10.png), метки версий (v2.13) или элементы вроде "10 apples" и "2 oranges".
Синтаксис
natsort(array &$array): truenatsort() принимает массив по ссылке, сортирует его на месте и (начиная с PHP 8.2) всегда возвращает true. В более старых версиях тип возвращаемого значения — bool. Поскольку массив изменяется непосредственно, вам не нужно присваивать результат обратно — после вызова читайте исходную переменную.
Как использовать функцию natsort()
Сравните естественный порядок с обычной алфавитной сортировкой sort():
$fruits = array("10 apples", "2 oranges", "100 bananas");
natsort($fruits);
print_r($fruits);Результат:
Array
(
[1] => 2 oranges
[0] => 10 apples
[2] => 100 bananas
)Обратите внимание: исходные ключи (1, 0, 2) сохраняются и перемещаются вместе со своими значениями — natsort() является сортировкой с сохранением ключей, как и asort(). Если бы вы использовали обычный sort(), то получили бы алфавитный (с переиндексацией) результат:
Array
(
[0] => 10 apples
[1] => 100 bananas
[2] => 2 oranges
)Здесь "100 bananas" оказывается посередине, потому что sort() сравнивает посимвольно.
Сортировка имён файлов
Классический случай применения — упорядочивание имён файлов, заканчивающихся числами:
$files = array("file20", "file3", "file1");
natsort($files);
print_r($files);Результат:
Array
(
[2] => file1
[1] => file3
[0] => file20
)Обычная сортировка поставила бы file20 перед file3 — что редко является желаемым результатом при выводе списка файлов.
natsort() чувствительна к регистру
natsort() сравнивает прописные буквы раньше строчных (ASCII-коды прописных букв меньше). При смешанном регистре заглавные буквы оказываются в начале:
$images = array("img12", "img10", "IMG2", "img1");
natsort($images);
print_r($images);Результат:
Array
(
[2] => IMG2
[3] => img1
[1] => img10
[0] => img12
)IMG2 стоит перед строчными именами. Если регистр нужно игнорировать, используйте регистронезависимый вариант natcasesort():
$images = array("img12", "img10", "IMG2", "img1");
natcasesort($images);
print_r($images);Результат:
Array
(
[3] => img1
[2] => IMG2
[1] => img10
[0] => img12
)Предостережения и ограничения
- Ключи сохраняются. Если после сортировки нужен чистый индекс с нуля, выполните
array_values($array). - Сортировка выполняется на месте. Массив передаётся по ссылке; не пишите
$x = natsort($arr)— это сохранит булево возвращаемое значение, а не отсортированный массив. - По умолчанию чувствительна к регистру. Используйте
natcasesort(), когда регистр не должен влиять на порядок. - Только массивы.
natsort()не работает со строками или объектами. Чтобы упорядочить строку с разделителями, разбейте её черезexplode()на массив, отсортируйте, затем объедините обратно черезimplode(). - Попарное сравнение. Внутри используется та же логика, что и в
strnatcmp(); для пользовательских правил сортировки используйтеusort()с собственным компаратором.
Заключение
natsort() сортирует массив в удобном для человека естественном порядке, воспринимая встроенные числа как числовые значения, сохраняя при этом ключи массива. Используйте её для имён файлов, строк версий и любых списков, смешивающих текст с числами — переключайтесь на natcasesort(), когда регистр не должен иметь значения, и не забывайте переиндексировать с помощью array_values(), если нужны последовательные ключи. Для других задач сортировки изучите связанные функции сортировки массивов.