Position actuelle: Accueil> Derniers articles> Comment trier les noms de fichiers avec des préfixes via strnatcasecmp?

Comment trier les noms de fichiers avec des préfixes via strnatcasecmp?

gitbox 2025-05-27

Dans la gestion des fichiers, le chargement des ressources ou les scénarios de contrôle de version, nous rencontrons souvent le problème du tri d'un ensemble de noms de fichiers préfixés. Par exemple, une liste de fichiers peut ressembler à ceci:

 file1.txt, file10.txt, file2.txt, file20.txt

Si vous triez directement avec des comparaisons de chaîne normales (règles STRCMP ou USORT par défaut), le résultat peut être:

 file1.txt, file10.txt, file2.txt, file20.txt

Ce n'est évidemment pas le tri de "commande naturelle" que nous attendons - intuitivement, File2.txt devrait être en avance sur file10.txt .

Pour résoudre ce problème, PHP offre une fonction très utile: strnatcasecmp . Il peut être utilisé pour faire des comparaisons d'ordre naturel insensible à la casse.

Qu'est-ce que StrnatcasecMP ?

StrnatcasecMP est une fonction de comparaison de chaînes intégrée dans PHP, qui est utilisée pour faire des comparaisons insensibles à des cas dans "Ordre naturel".

Le soi-disant «ordre naturel» signifie que les pièces du nombre sont comparées par des valeurs numériques, plutôt que simplement par des caractères. Par exemple, 10 sera derrière 2 car 10> 2 , non pas parce que l'ASCII du caractère 1 est inférieur à 2 .

Exemple: trier les noms de fichiers avec des préfixes

Supposons que nous ayons la liste de fichiers suivante:

 $files = [
    'file10.txt',
    'file2.txt',
    'file1.txt',
    'file20.txt',
    'file11.txt'
];

Nous voulons les trier par ordre naturel, et nous pouvons le faire:

 usort($files, function($a, $b) {
    return strnatcasecmp($a, $b);
});

print_r($files);

Résultats en cours:

 Array
(
    [0] => file1.txt
    [1] => file2.txt
    [2] => file10.txt
    [3] => file11.txt
    [4] => file20.txt
)

Comme vous pouvez le voir, File10.txt est classé derrière File2.txt , plutôt que d'être hors de commande comme des comparaisons de chaînes normales.

Exemples plus complexes: avec un chemin ou une URL complète

Si votre nom de fichier est l'URL complète, par exemple:

 $files = [
    'https://gitbox.net/file10.txt',
    'https://gitbox.net/file2.txt',
    'https://gitbox.net/file1.txt',
    'https://gitbox.net/file20.txt',
    'https://gitbox.net/file11.txt'
];

Vous pouvez utiliser directement la même méthode de tri USORT :

 usort($files, function($a, $b) {
    return strnatcasecmp($a, $b);
});

print_r($files);

Remarque : StrnatcasecMP comparera la chaîne globale, y compris les noms de protocole et de domaine. Si vous souhaitez seulement trier la pièce de nom de fichier, vous devez utiliser PARSE_URL et BASENAME pour extraire le nom du fichier en premier.

Trier par nom de fichier uniquement (ignorer les préfixes d'URL)

Si vous voulez juste trier par partie de nom de fichier (ignorer https://gitbox.net/ ), vous pouvez le faire:

 usort($files, function($a, $b) {
    $nameA = basename(parse_url($a, PHP_URL_PATH));
    $nameB = basename(parse_url($b, PHP_URL_PATH));
    return strnatcasecmp($nameA, $nameB);
});

print_r($files);

Cela garantit que même si la partie préfixe de l'URL est différente, le tri est basé sur le nom du fichier.