Естественная сортировка строк в PHP: natsort()
Руководство по реализации естественной сортировки строк в PHP с помощью natsort(). Корректная сортировка числовых и текстовых строк.
Как реализовать естественную сортировку строк в PHP, чтобы строки, начинающиеся с чисел (например, ‘1 строка’, ‘2 строка’, ‘11 строка’), сортировались по числовому значению, а не по первому символу, и строки без чисел сортировались по алфавиту?
Для реализации естественной сортировки строк в PHP, где строки с числами (например, ‘1 строка’, ‘11 строка’) упорядочиваются по числовому значению, а текстовые строки — по алфавиту, используйте встроенную функцию natsort(). Она автоматически обрабатывает числа в начале строк как числовые значения, избегая лексикографического порядка, и корректно сортирует нечисловые строки в алфавитной последовательности.
Содержание
- Как работает естественная сортировка в PHP
- Пример реализации с natsort()
- Особенности сортировки кириллических строк
- Альтернативный метод через usort()
- Источники
- Заключение
Как работает естественная сортировка в PHP
Функция natsort() использует алгоритм естественной сортировки, который разбивает строки на части и обрабатывает числа как числовые значения, а не символы. Например, строка '11 строка' будет интерпретироваться как число 11, а не как набор символов '1' и '1'. Это гарантирует, что '11 строка' окажется после '2 строка', в отличие от стандартной сортировки sort(), где '11' шло бы перед '2'.
Важно: natsort() сохраняет ассоциативные ключи массива, что критично при работе с именованными данными. Для регистронезависимой сортировки используйте natcasesort(), но для кириллицы требуется дополнительная настройка локали.
Пример реализации с natsort()
<?php
$items = ['11 строка', '2 строка', '1 строка', 'яблоко', 'арбуз'];
// Настройка локали для корректной кириллической сортировки
setlocale(LC_ALL, 'ru_RU.UTF-8');
natsort($items);
print_r(array_values($items)); // Сброс индексов для нумерованного вывода
Результат:
Array
(
[0] => 1 строка
[1] => 2 строка
[2] => 11 строка
[3] => арбуз
[4] => яблоко
)
Здесь числовые строки отсортированы по возрастанию чисел, а текстовые — по алфавиту (арбуз → яблоко). Функция array_values() сбрасывает оригинальные ключи для удобного вывода.
Особенности сортировки кириллических строк
По умолчанию PHP сортирует строки в кодировке ASCII, что приводит к некорректному порядку кириллицы (например, «я» может идти перед «а»). Чтобы избежать этого:
- Убедитесь, что файл сохранен в UTF-8.
- Установите локаль перед сортировкой:
setlocale(LC_ALL, 'ru_RU.UTF-8');
- Для веб-приложений добавьте заголовок:
header('Content-Type: text/html; charset=utf-8');
Без этих шагов сортировка кириллических строк может выдавать неожиданные результаты, особенно на серверах с локалью по умолчанию C или en_US.
Альтернативный метод через usort()
Если требуется кастомная логика (например, обработка чисел не только в начале строки), создайте пользовательскую функцию сравнения:
<?php
function naturalSortCompare($a, $b) {
$aNum = preg_match('/^\d+/', $a, $matches) ? (int)$matches[0] : null;
$bNum = preg_match('/^\d+/', $b, $matches) ? (int)$matches[0] : null;
// Если обе строки начинаются с чисел — сравниваем числа
if ($aNum !== null && $bNum !== null) {
return $aNum <=> $bNum;
}
// Если одна строка начинается с числа, а другая — нет
if ($aNum !== null) return -1;
if ($bNum !== null) return 1;
// Иначе сортируем алфавитно
return strcmp($a, $b);
}
$items = ['11 строка', 'б строка', '2 строка', 'а строка'];
usort($items, 'naturalSortCompare');
Этот метод гибче, но требует больше кода. Используйте его, только если natsort() не покрывает специфические сценарии.
Источники
- PHP: natsort — Документация по естественной сортировке — Официальное описание функции и её поведение: https://www.php.net/manual/ru/function.natsort.php
- PHP: setlocale — Настройка локали для сортировки — Руководство по корректной обработке кириллицы: https://www.php.net/manual/ru/function.setlocale.php
- Natural Sort Order in PHP — Примеры и углубленный анализ — Практическое применение алгоритма: https://www.php.net/manual/ru/function.natsort.php#110044
Заключение
Для естественной сортировки строк в PHP с приоритетом чисел в начале используйте natsort(), предварительно настроив локаль через setlocale(LC_ALL, 'ru_RU.UTF-8'). Этот метод решает задачу «из коробки», избегая ошибок лексикографического порядка. Если нужны кастомные правила, реализуйте usort() с регулярными выражениями. Всегда проверяйте сортировку на реальных данных, особенно при работе с кириллицей — корректная локаль критична для алфавитного порядка.
Для естественной сортировки строк в PHP используйте функцию natsort(). Эта функция учитывает числа в строках и сортирует их как числа. Например: natsort($array);.
Если нужно сохранить оригинальный порядок индексов, используйте natcasesort() для нечувствительной к регистру сортировки.
Пример использования:
$items = ['1 строка', '2 строка', '11 строка', 'яблоко', 'банан'];
natsort($items);
print_r($items);
Результат:
- 1 строка
- 2 строка
- 11 строка
- банан
- яблоко
В PHP для естественной сортировки можно использовать функцию natsort. Согласно документации: natsort — Сортирует массив в порядке, соответствующем естественному порядку чисел.
Пример:
$items = ['1.1', '1.10', '1.2', '1.20'];
natsort($items);
print_r($items);
Вывод:
- 1.1
- 1.2
- 1.10
- 1.20
Для нечувствительной к регистру сортировки используйте natcasesort().
Официальная документация: natsort
Если стандартные функции не подходят, можно реализовать собственный алгоритм с помощью preg_match и usort. Пример:
function natural_sort($a, $b) {
$pattern = '/(\d+)/';
preg_match($pattern, $a, $matchesA);
preg_match($pattern, $b, $matchesB);
if (!empty($matchesA[1]) && !empty($matchesB[1])) {
return $matchesA[1] - $matchesB[1];
}
return strcmp($a, $b);
}
usort($array, 'natural_sort');
Этот метод позволяет гибко настраивать правила сортировки. Однако для большинства случаев natsort достаточно эффективен.
Дополнительная информация: Stack Overflow — Natural sort in PHP
