Strnatcasecmp: примеры (PHP)
strnatcasecmp(string string1, string string2): intФункция strnatcasecmp в PHP
Функция strnatcasecmp в PHP служит для сравнения двух строк по алгоритму «естественного порядка» с игнорированием регистра символов. Этот метод сравнения полезен, когда строки содержат числа, так как он учитывает их числовое значение, а не лексикографический порядок, что приводит к более интуитивно понятным для человека результатам сортировки. Функция часто применяется для сортировки списков файлов, названий товаров с артикулами или любых данных, где числовая часть является значимой.
Функция принимает два обязательных аргумента:
- string1 (string): Первая строка для сравнения.
- string2 (string): Вторая строка для сравнения.
Функция возвращает целое число: меньше 0, если string1 меньше string2; больше 0, если string1 больше string2; и 0, если строки равны с учётом естественного порядка и без регистра.
Примеры использования strnatcasecmp
Стандартное сравнение строк (strcmp) анализирует символы по кодам ASCII, в то время как естественное сравнение распознает числовые последовательности.
<?
$result1 = strnatcasecmp('Image2.jpg', 'Image10.jpg');
$result2 = strcasecmp('Image2.jpg', 'Image10.jpg');
echo "strnatcasecmp: $result1\n";
echo "strcasecmp: $result2\n";
?>strnatcasecmp: -1 strcasecmp: 1
Первый результат (-1) указывает, что 'Image2.jpg' меньше 'Image10.jpg' (2 < 10), что логично. Второй результат (1) показывает, что обычное сравнение считает 'Image2.jpg' больше, потому что символ '2' идет после символа '1'.
<?
$result = strnatcasecmp('APPLE', 'apple');
echo $result;
?>0
Функция возвращает 0, так как строки идентичны при игнорировании регистра букв.
<?
$result = strnatcasecmp('release-1.2.3', 'release-1.12.0');
echo $result;
?>-1
Здесь 1.2.3 меньше, чем 1.12.0, потому что 2 < 12.
Похожие функции в PHP
- strnatcmp: Проводит аналогичное естественное сравнение, но является регистрозависимой. Предпочтительна, когда различие между заглавными и строчными буквами важно.
- strcasecmp: Бинарно безопасное сравнение строк без учета регистра, но не использующее алгоритм естественного порядка. Подходит для простого регистронезависимого сравнения, где нет числовых данных.
- strcmp: Бинарно безопасное регистрозависимое сравнение. Базовый инструмент для точного сравнения строк.
- similar_text, levenshtein: Функции для оценки схожести строк, а не для их упорядочивания. Используются в задачах нечеткого поиска.
Выбор функции зависит от задачи: для сортировки названий файлов или версий лучше подходит strnatcasecmp; для точного сравнения паролей или ключей — strcmp.
Типичные ошибки
Частая ошибка — ожидание булевых true/false. Функция возвращает целое число.
<?
// Неправильно:
if (strnatcasecmp('строка1', 'строка2')) {
echo 'Строки не равны';
}
// Такое условие сработает даже при -1, что трактуется как true.
// Правильно:
if (strnatcasecmp('строка1', 'строка2') !== 0) {
echo 'Строки не равны';
}
?>Возвращаемое значение указывает на отношение первого аргумента ко второму. Если результат меньше нуля, первая строка меньше второй. Это важно учитывать при использовании в пользовательских функциях сортировки.
<?
$array = ['img12.png', 'img2.png', 'img1.png'];
usort($array, 'strnatcasecmp'); // Сортирует по возрастанию
print_r($array);
?>Array
(
[0] => img1.png
[1] => img2.png
[2] => img12.png
)Изменения в последних версиях PHP
Начиная с PHP 8.0.0, функция strnatcasecmp теперь выбрасывает исключение TypeError при передаче не строковых аргументов, в отличие от предыдущих версий, где такие аргументы преобразовывались в строки или вызывали предупреждение. Это изменение соответствует общей политике строгой типизации в PHP 8.
<?
// PHP 7 и ранее: возможно предупреждение, но сравнение продолжится.
// PHP 8.0.0 и выше: фатальная ошибка TypeError.
try {
$result = strnatcasecmp('text', []);
} catch (TypeError $e) {
echo $e->getMessage();
}
?>strnatcasecmp(): Argument #2 ($string2) must be of type string, array given
Расширенные примеры применения
<?
$products = [
['name' => 'Widget v2', 'sku' => 'item-2'],
['name' => 'Widget v12', 'sku' => 'item-12'],
['name' => 'widget v1', 'sku' => 'item-1'],
];
usort($products, function($a, $b) {
return strnatcasecmp($a['name'], $b['name']);
});
print_r($products);
?>Array
(
[0] => Array
(
[name] => widget v1
[sku] => item-1
)
[1] => Array
(
[name] => Widget v2
[sku] => item-2
)
[2] => Array
(
[name] => Widget v12
[sku] => item-12
)
)Сравнение введенного пользователем поискового запроса с игнорированием регистра и учетом чисел в названиях.
<?
$searchTerm = 'model 2023';
$databaseEntries = ['Model 2022', 'MODEL 2023', 'Model 2021', 'model 2024'];
$matches = array_filter($databaseEntries, function($entry) use ($searchTerm) {
return strnatcasecmp($entry, $searchTerm) === 0;
});
print_r($matches);
?>Array
(
[1] => MODEL 2023
)<?
class Document {
public function __construct(public string $title) {}
}
$docs = [
new Document('Report 10'),
new Document('report 2'),
new Document('Report 1'),
];
usort($docs, function($a, $b) {
return strnatcasecmp($a->title, $b->title);
});
foreach ($docs as $doc) {
echo $doc->title . "\n";
}
?>Report 1 report 2 Report 10
Аналоги функции в других языках
Strnatcasecmp в Python
В стандартной библиотеке нет прямой аналогии. Для естественной сортировки без учета регистра используют комбинацию str.casefold и библиотеки natsort или собственную реализацию.
import natsort
list1 = ['Image2.jpg', 'Image10.jpg', 'image1.jpg']
sorted_list = natsort.natsorted(list1, alg=natsort.IC)
print(sorted_list)['image1.jpg', 'Image2.jpg', 'Image10.jpg']
Strnatcasecmp в Javascript
Аналогично, для естественной сортировки без учета регистра применяют сторонние библиотеки или Intl.Collator с числовым опцией.
const items = ['Image2.jpg', 'Image10.jpg', 'image1.jpg'];
const collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
items.sort(collator.compare);
console.log(items);['image1.jpg', 'Image2.jpg', 'Image10.jpg']
Strnatcasecmp в MySQL
Оператор сравнения строк не имеет встроенного естественного алгоритма. Обычно сортировку выполняют после извлечения данных в приложение.