Como obter a ordenação unix na mesma ordem que Java (por valor unicode)

5

Eu descubro a classificação para o comando unix sort em um programa Java que eu escrevi. No entanto, estou tendo problemas decorrentes da comparação de strings do Java se comportando de maneira diferente das comparações feitas por classificação.

Do [Java Doc] [1]:

Compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings.

Na página de manual de classificação:

* WARNING * The locale specified by the environment affects sort order. Set LC_ALL=C to get the traditional sort order that uses native byte values.

Então, acho que é preciso classificar com LC_ALL = C. No entanto, sempre achei que isso significava classificar com base no valor ASCII, o que significa quem sabe o que poderia acontecer com o unicode.

    
por Zugwalt 16.02.2012 / 23:36

1 resposta

7

A categoria LC_COLLATE locale controla a ordem de classificação. LC_ALL define todas as categorias.

Com LC_COLLATE=C , as sequências são ordenadas byte por byte. Os bytes não precisam ser caracteres ASCII (somente valores de bytes entre 0 e 127 são ASCII). Em um sistema unix, o Unicode é quase sempre codificado como UTF-8 . O UTF-8 tem a propriedade de que a codificação de caracteres como seqüências de bytes preserva sua ordenação, e assim ordenar strings UTF-8 em ordem lexicográfica de bytes é equivalente a classificá-las em ordem lexicográfica de caracteres. Portanto LC_COLLATE=C é adequado para ordenar Unicode codificado em UTF-8 lexicograficamente de acordo com os valores dos caracteres.

Observe que o Java na verdade não classifica de acordo com os valores de caractere Unicode, mas de acordo com a codificação UTF-16. Isso faz diferença com pares substitutos , ou seja, se você tiver pontos de código acima de 65535.

Nem a ordenação por representação de bytes UTF-8 nem a ordenação Java nem o utilitário sort em um código de idioma UTF-8 no GNU / Linux usam combinando caracteres em conta, por exemplo (U + 0061 LETRA PEQUENA A seguido por U + 0301 COMBINANDO AGUDA ACENTUADA) é classificado de forma diferente de á (U + 00E1 LATINA PEQUENA LETRA A COM AGUDO) (em uma localidade UTF-8, ambos terminam equivalentes para a na primeira passagem, mas a segunda passagem classifica por ponto de código).

    
por 17.02.2012 / 09:37