¿Cómo alfabetizar cadenas con diacríticos?

7

P: ¿cómo alfabetizo cadenas con signos diacríticos?

Problema

Tengo una larga lista de nombres de autores, algunos de los cuales tienen letras con signos diacríticos en sus nombres (por ejemplo, "á" o "é"). Quiero ordenar esta lista alfabéticamente.

El problema: sorting la lista con string-lesspqué no ordenar alfabéticamente.

De acuerdo con la respuesta aceptada en esta publicación de un sitio hermano , el inglés ignora los signos diacríticos en la clasificación, excepto para romper los lazos. (Otros idiomas lo hacen de manera diferente).

Ejemplo de juguete

Aquí hay un ejemplo de juguete. La lista de letras con las que empiezo ya está ordenada alfabéticamente. Cuando sortesta lista con string-lessp, sin embargo, que los ordena en lo que supongo es el punto para Unicode en lugar de por orden alfabético:

(let ((letters '("a" "à" "á" "â" "b" "c" "e" "é" "ê")))
  (sort letters #'string-lessp))
;; => ("a" "b" "c" "e" "à" "á" "â" "é" "ê")

¿Qué debo hacer?

¿Cómo puedo alfabetizar cadenas con signos diacríticos?

Como mínimo, me gustaría respetar la regla de "ignorar los signos diacríticos excepto para romper los lazos" descrita anteriormente. Idealmente, me gustaría poder alfabetizar de acuerdo con un idioma definido arbitrariamente, pero felizmente me conformaré con el inglés.

Dan
fuente
Buena pregunta. Me pregunto si depende, o debería depender, de la configuración de idioma de su sistema operativo. La alfabetización depende del idioma, en general.
Drew

Respuestas:

8

Si la configuración regional de su sistema está configurada en algo que cotejará correctamente los signos diacríticos ( no POSIX ), esto debería funcionar para usted:

(let ((letters '("é" "a" "à" "c" "â" "b" "á" "e" "ê")))
  (sort letters #'string-collate-lessp))
;; => ("a" "á" "à" "â" "b" "c" "e" "é" "ê")

Si eso no funciona, puede proporcionar una cadena de configuración regional como tercer argumento string-collate-lessppara obtener lo que desea. Con inglés americano en un sistema POSIX, por ejemplo:

(let ((letters '("é" "a" "à" "c" "â" "b" "á" "e" "ê")))
  (sort letters (lambda (a b) (string-collate-lessp a b "en_US.UTF-8"))))

(Para inglés americano en MS-Windows, reemplace "en_US.UTF-8"con "enu_USA.1252").

Si desea profundizar un poco más en esto para ver qué sucede debajo del capó, le recomiendo echar un vistazo a la definición de función de str_collatein src/sysdep.c.

Sam
fuente
Exactamente lo que estaba buscando, ¡gracias! Como comentario adicional, ¿podría mencionar dónde se pueden buscar las cadenas locales para los idiomas de inglés no estadounidense?
Dan
@Dan Esa es información dependiente del sistema AFAIK. Aunque no es una lista de identificadores locales, estas preguntas y respuestas de unix.stackexchange deberían ayudarlo a formular buenos valores en la mayoría de los sistemas similares a Unix.
Sam
¡Gracias por el seguimiento!
Dan