Una solución completa de UCA
La forma más sencilla, fácil y directa de hacerlo es hacer una llamada al módulo de la biblioteca Perl, Unicode :: Collate :: Locale , que es una subclase del módulo Unicode :: Collate estándar . Todo lo que necesita hacer es pasar al constructor un valor de configuración regional "xv"
para Suecia.
(Es posible que no necesariamente aprecie esto para el texto sueco, pero debido a que Perl usa caracteres abstractos, puede usar cualquier punto de código Unicode que desee, ¡sin importar la plataforma o compilación! Pocos idiomas ofrecen tal conveniencia. Lo menciono porque he luchado contra un perdiendo mucho la batalla con Java por este enloquecedor problema últimamente).
El problema es que no sé cómo acceder a un módulo de Perl desde Python, es decir, aparte de usar una llamada de shell o una tubería de dos lados. Con ese fin, le he proporcionado un script de trabajo completo llamado ucsort al que puede llamar para hacer exactamente lo que ha pedido con perfecta facilidad.
Este script es 100% compatible con el algoritmo de clasificación Unicode completo , ¡con todas las opciones de adaptación compatibles! Y si tiene un módulo opcional instalado o ejecuta Perl 5.13 o mejor, entonces tiene acceso completo a configuraciones regionales CLDR fáciles de usar. Vea abajo.
Demostración
Imagine un conjunto de entrada ordenado de esta manera:
b o i j n l m å y e v s k h d f g t ö r x p z a ä c u q
Una clasificación predeterminada por punto de código produce:
a b c d e f g h i j k l m n o p q r s t u v x y z ä å ö
lo cual es incorrecto según el libro de todos. Usando mi script, que usa el algoritmo de intercalación Unicode, obtienes este orden:
% perl ucsort /tmp/swedish_alphabet | fmt
a å ä b c d e f g h i j k l m n o ö p q r s t u v x y z
Ese es el tipo UCA predeterminado. Para obtener la configuración regional sueca, llame a ucsort de esta manera:
% perl ucsort --locale=sv /tmp/swedish_alphabet | fmt
a b c d e f g h i j k l m n o p q r s t u v x y z å ä ö
Aquí hay una demostración de entrada mejor. Primero, el conjunto de entrada:
% fmt /tmp/swedish_set
cTD cDD Cöd Cbd cAD cCD cYD Cud cZD Cod cBD Cnd cQD cFD Ced Cfd cOD
cLD cXD Cid Cpd cID Cgd cVD cMD cÅD cGD Cqd Cäd cJD Cdd Ckd cÖD cÄD
Ctd Czd Cxd cHD cND cKD Cvd Chd Cyd cUD Cld Cmd cED Crd Cad Cåd Ccd
cRD cSD Csd Cjd cPD
Por punto de código, eso se ordena de esta manera:
Cad Cbd Ccd Cdd Ced Cfd Cgd Chd Cid Cjd Ckd Cld Cmd Cnd Cod Cpd Cqd
Crd Csd Ctd Cud Cvd Cxd Cyd Czd Cäd Cåd Cöd cAD cBD cCD cDD cED cFD
cGD cHD cID cJD cKD cLD cMD cND cOD cPD cQD cRD cSD cTD cUD cVD cXD
cYD cZD cÄD cÅD cÖD
Pero el uso del UCA predeterminado hace que se ordene de esta manera:
% ucsort /tmp/swedish_set | fmt
cAD Cad cÅD Cåd cÄD Cäd cBD Cbd cCD Ccd cDD Cdd cED Ced cFD Cfd cGD
Cgd cHD Chd cID Cid cJD Cjd cKD Ckd cLD Cld cMD Cmd cND Cnd cOD Cod
cÖD Cöd cPD Cpd cQD Cqd cRD Crd cSD Csd cTD Ctd cUD Cud cVD Cvd cXD
Cxd cYD Cyd cZD Czd
Pero en la configuración regional sueca, de esta manera:
% ucsort --locale=sv /tmp/swedish_set | fmt
cAD Cad cBD Cbd cCD Ccd cDD Cdd cED Ced cFD Cfd cGD Cgd cHD Chd cID
Cid cJD Cjd cKD Ckd cLD Cld cMD Cmd cND Cnd cOD Cod cPD Cpd cQD Cqd
cRD Crd cSD Csd cTD Ctd cUD Cud cVD Cvd cXD Cxd cYD Cyd cZD Czd cÅD
Cåd cÄD Cäd cÖD Cöd
Si prefiere ordenar en mayúsculas antes que en minúsculas, haga esto:
% ucsort --upper-before-lower --locale=sv /tmp/swedish_set | fmt
Cad cAD Cbd cBD Ccd cCD Cdd cDD Ced cED Cfd cFD Cgd cGD Chd cHD Cid
cID Cjd cJD Ckd cKD Cld cLD Cmd cMD Cnd cND Cod cOD Cpd cPD Cqd cQD
Crd cRD Csd cSD Ctd cTD Cud cUD Cvd cVD Cxd cXD Cyd cYD Czd cZD Cåd
cÅD Cäd cÄD Cöd cÖD
Clasificaciones personalizadas
Puede hacer muchas otras cosas con ucsort . Por ejemplo, aquí se explica cómo ordenar los títulos en inglés:
% ucsort --preprocess='s/^(an?|the)\s+//i' /tmp/titles
Anathem
The Book of Skulls
A Civil Campaign
The Claw of the Conciliator
The Demolished Man
Dune
An Early Dawn
The Faded Sun: Kesrith
The Fall of Hyperion
A Feast for Crows
Flowers for Algernon
The Forbidden Tower
Foundation and Empire
Foundation’s Edge
The Goblin Reservation
The High Crusade
Jack of Shadows
The Man in the High Castle
The Ringworld Engineers
The Robots of Dawn
A Storm of Swords
Stranger in a Strange Land
There Will Be Time
The White Dragon
Necesitará Perl 5.10.1 o mejor para ejecutar el script en general. Para obtener soporte de configuración regional, debe instalar el módulo CPAN opcional Unicode::Collate::Locale
. Alternativamente, puede instalar versiones de desarrollo de Perl, 5.13+, que incluyen ese módulo de manera estándar.
Convenciones de llamadas
Este es un prototipo rápido, por lo que ucsort no está documentado en su mayoría. Pero esta es su SINOPSIS de qué conmutadores / opciones acepta en la línea de comando:
# standard options
--help|?
--man|m
--debug|d
# collator constructor options
--backwards-levels=i
--collation-level|level|l=i
--katakana-before-hiragana
--normalization|n=s
--override-CJK=s
--override-Hangul=s
--preprocess|P=s
--upper-before-lower|u
--variable=s
# program specific options
--case-insensitive|insensitive|i
--input-encoding|e=s
--locale|L=s
--paragraph|p
--reverse-fields|last
--reverse-output|r
--right-to-left|reverse-input
Sí, está bien: esa es realmente la lista de argumentos que uso para la llamada Getopt::Long
, pero entiendes la idea. :)
Si puede descubrir cómo llamar a los módulos de la biblioteca de Perl desde Python directamente sin llamar a un script de Perl, hágalo. Yo solo no sé cómo. Me encantaría aprender a hacerlo.
Mientras tanto, creo que este script hará lo que necesita hacer en todo su particular, ¡ y más! Ahora lo uso para toda la clasificación de texto. Que finalmente hace lo que he necesitado desde hace mucho, mucho tiempo.
El único inconveniente es que el --locale
argumento hace que el rendimiento baje por los tubos, aunque es lo suficientemente rápido para una clasificación normal, no local, pero aún 100% compatible con UCA . Dado que carga todo en la memoria, probablemente no desee utilizar esto en documentos de gigabytes. Lo uso muchas veces al día, y seguro que es genial tener por fin una ordenación sensata de texto.