Uma solução UCA completa
A maneira mais simples, fácil e direta de fazer isso é fazer um callout para o módulo da biblioteca Perl, Unicode :: Collate :: Locale , que é uma subclasse do módulo Unicode :: Collate padrão . Tudo o que você precisa fazer é passar ao construtor um valor de localidade "xv"
para Suécia.
(Você pode não necessariamente apreciar isso para texto em sueco, mas como Perl usa caracteres abstratos, você pode usar qualquer ponto de código Unicode que quiser - não importa a plataforma ou compilação! Poucos idiomas oferecem essa conveniência. Menciono isso porque estou lutando contra um perdendo muito a batalha com o Java por causa desse problema enlouquecedor ultimamente.)
O problema é que não sei como acessar um módulo Perl do Python - exceto, isto é, usando um callout shell ou um pipe de dois lados. Para esse fim, forneci a você um script de trabalho completo chamado ucsort, que você pode chamar para fazer exatamente o que pediu com perfeita facilidade.
Este script é 100% compatível com o Unicode Collation Algorithm completo , com todas as opções de personalização suportadas !! E se você tiver um módulo opcional instalado ou executar Perl 5.13 ou superior, terá acesso total aos locais CLDR fáceis de usar. Ver abaixo.
Demonstração
Imagine um conjunto de entrada ordenado desta forma:
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
Uma classificação padrão por ponto de código produz:
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 ä å ö
o que está incorreto no livro de todos. Usando meu script, que usa o algoritmo de agrupamento Unicode, você obtém esta ordem:
% 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
Essa é a classificação UCA padrão. Para obter a localidade sueca, chame ucsort desta forma:
% 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 å ä ö
Aqui está uma demonstração de entrada melhor. Primeiro, o 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 ponto de código, isso classifica desta forma:
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
Mas usar o UCA padrão faz com que seja classificado da seguinte maneira:
% 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
Mas na localidade sueca, desta forma:
% 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
Se você preferir letras maiúsculas antes de letras minúsculas, faça o seguinte:
% 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
Ordenações Personalizadas
Você pode fazer muitas outras coisas com o ucsort . Por exemplo, aqui está como classificar títulos em 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
Você precisará do Perl 5.10.1 ou superior para executar o script em geral. Para suporte local, você deve instalar o módulo CPAN opcional Unicode::Collate::Locale
. Como alternativa, você pode instalar uma versão de desenvolvimento do Perl, 5.13+, que inclui esse módulo padrão.
Convenções de chamada
Este é um protótipo rápido, então ucsort está quase totalmente sub (der) documentado. Mas este é o seu SINOPSE de quais interruptores / opções ele aceita na linha 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
Sim, ok: essa é realmente a lista de argumentos que uso para a chamada para Getopt::Long
, mas essa é a ideia. :)
Se você puder descobrir como chamar os módulos da biblioteca Perl diretamente do Python sem chamar um script Perl, faça-o com certeza. Eu só não sei como. Adoraria aprender como.
Nesse ínterim, acredito que este script fará o que você precisa em todas as suas particularidades - e muito mais! Agora eu uso isso para toda a classificação de texto. Ele finalmente faz o que eu precisava de um longo, longo tempo.
A única desvantagem é que o --locale
argumento faz com que o desempenho diminua, embora seja rápido o suficiente para classificação normal, não local, mas ainda 100% compatível com UCA . Uma vez que carrega tudo na memória, você provavelmente não deseja usar isso em documentos gigabyte. Eu o uso várias vezes ao dia, e com certeza é ótimo ter finalmente uma classificação sensata de texto.