Confusión en el orden de clasificación natural

La mayoría de los administradores de archivos gráficos no ordenan estrictamente lexicográficamente, sino que utilizan una “clasificación natural”. Los bloques de números en el nombre se interpretan como números: el bloque de números más grande gana, incluso si en términos puramente alfabéticos saliera lo contrario. La idea detrás de la clasificación natural: lo que la gente quiere principalmente es "9 antes del 10", "Capítulo 2 antes del Capítulo 10", sin tener que agregar ceros a la izquierda.


Los siguientes pares de archivos se ordenan naturalmente en orden ascendente de la siguiente manera:

  • build-9e2.log
  • build-950.log

Sorprendente, pero explicable: el primer bloque numérico \(9\) es más pequeño que el primer bloque numérico \(950\) .

  • IMG_12113419_90.jpg
  • IMG_0554363070_90.jpg

El número \(12113419\) es menor que \(554363070\) (se elimina el \(0\) inicial).

  • temp_0C.txt
  • temp_2C.txt
  • temp_-3C.txt
  • temp_10C.txt
  • temp_-12C.txt

Los números comparados son \(0\) , \(2\) , \(3\) , \(10\) , \(12\) – el “-” no se considera parte del número.

Ni siquiera el orden alfabético es unívoco en su conjunto: el uso de mayúsculas, diéresis como ä (alemán) o letras de varios caracteres como ch (checo) dan lugar a variantes legítimas. Por lo tanto, el orden alfabético puro depende del contexto. El Explorador de Windows implementa esto en la función StrCmpLogicalW . Si bien su código fuente (shlwapi.dll) es propietario y no público, existen reimplementaciones, por ejemplo, de ReactOS.:

{
    TRACE("%s, %s\n", wine_dbgstr_w(str), wine_dbgstr_w(comp));
 
    if (!str || !comp)
        return 0;
 
    while (*str)
    {
        if (!*comp)
            return 1;
        else if (*str >= '0' && *str <= '9')
        {
            int str_value, comp_value;
 
            if (*comp < '0' || *comp > '9')
                return -1;
 
            /* Compare the numbers */
            StrToIntExW(str, 0, &str_value);
            StrToIntExW(comp, 0, &comp_value);
 
            if (str_value < comp_value)
                return -1;
            else if (str_value > comp_value)
                return 1;
 
            /* Skip */
            while (*str >= '0' && *str <= '9') str++;
            while (*comp >= '0' && *comp <= '9') comp++;
        }
        else if (*comp >= '0' && *comp <= '9')
            return 1;
        else
        {
            int diff = ChrCmpIW(*str, *comp);
            if (diff > 0)
                return 1;
            else if (diff < 0)
                return -1;
 
            str++;
            comp++;
        }
    }
 
    if (*comp)
      return -1;
 
    return 0;
}

Google Drive, OneDrive, KDE y compañía muestran un comportamiento de clasificación similar. Herramientas CLI como ls y find ordenar de forma diferente a los administradores de archivos GUI. La semántica está en los nombres de los archivos, no en la API. Si desea resultados sin sorpresas, defina convenciones: separadores consistentes, números acolchados y un manejo claro de las unidades. Entonces lo “alfabético” vuelve a ser predecible.

Atrás