Por que o tipo diz que ɛ = e?


25

ɛ("Latin epsilon") é uma letra usada em certas línguas africanas, geralmente para representar o som da vogal no inglês "bed". No Unicode, é codificado como U + 025B, muito diferente do cotidiano e.

No entanto, se eu sorto seguinte:

eb
ed
ɛa
ɛc

parece que sortconsidera ɛe eequivalente:

ɛa
eb
ɛc
ed

Oque esta acontecendo aqui? E existe uma maneira de criar ɛe ediferenciar para sortpropósitos?


21
as regras de classificação são chamadas de 'agrupamento', se isso ajudar o seu pesquisador
BlueRaja - Danny Pflughoeft

11
Tente colocar um certo número de eamisturados ɛadentro de um arquivo de texto e classificá-lo. Você verá que sempre classifica eaantes ɛa. Então, não, eles não são considerados iguais.
Bakuriu 27/10/19

Pode ser um ponto óbvio, mas ainda não o vi sugerido explicitamente: se você estiver classificando palavras em $ (certos_africanos_language), a coisa natural a fazer é definir o código do idioma para $ (certos_africanos_language).
Federico Poloni 28/10

@FedericoPoloni Um ponto muito bom! Infelizmente, não consegui encontrar nenhuma localidade criada para esse idioma.
Draconis 28/10

11
@ GermánBouzas Este é especificamente o "epsilon latino", uma forma projetada para se encaixar no alfabeto latino. Eles têm a mesma aparência, mas o epsilon latino é U + 025B, enquanto o epsilon grego é U + 03B5.
Draconis

Respostas:


67

Não, não os considera equivalentes, apenas têm o mesmo peso principal. Para que, na primeira aproximação, eles tenham a mesma classificação.

Se você olhar para / usr / share / i18n / locales / iso14651_t1_common (usado como base para a maioria das localidades) em um sistema GNU (aqui com glibc 2.27), você verá:

<U0065> <e>;<BAS>;<MIN>;IGNORE # 259 e
<U025B> <e>;<PCL>;<MIN>;IGNORE # 287 ɛ
<U0045> <e>;<BAS>;<CAP>;IGNORE # 577 E

e, ɛE Etem o mesmo peso primário, ee Emesmo peso secundário, apenas o terceiro peso diferencia-os.

Ao comparar strings, sort(a strcoll()função libc padrão é usada para comparar strings) começa comparando os pesos primários de todos os caracteres e só vai para o segundo peso se os strings forem iguais aos pesos primários (e assim por diante com os outros pesos) .

É assim que o caso parece ser ignorado na ordem de classificação na primeira aproximação. Absortes entre aae ac, mas Abpode classificar antes ou depois ab, dependendo da regra de linguagem (algumas línguas têm <MIN>antes <CAP>como em Inglês Britânico, alguns <CAP>antes <MIN>como em estoniano).

Se etivesse a mesma ordem de classificação que ɛ, printf '%s\n' e ɛ | sort -uretornaria apenas uma linha. Mas como <BAS>antes <PCL>, eantes ɛ . eɛeclassifica depois EEE(no peso secundário), mesmo que EEEclassifique depois eee(para o qual precisamos subir até o terceiro peso).

Agora, se no meu sistema com glibc 2.27, eu corro:

sed -n 's/\(.*;[^[:blank:]]*\).*/\1/p' /usr/share/i18n/locales/iso14651_t1_common |
  sort -k2 | uniq -Df1

Você notará que existem alguns caracteres que foram definidos com exatamente os mesmos 4 pesos. Em particular, nosso ɛ tem os mesmos pesos que:

<U01DD> <e>;<PCL>;<MIN>;IGNORE
<U0259> <e>;<PCL>;<MIN>;IGNORE
<U025B> <e>;<PCL>;<MIN>;IGNORE

E com certeza:

$ printf '%s\n' $'\u01DD' $'\u0259' $'\u025B' | sort -u
ǝ
$ expr ɛ = ǝ
1

Isso pode ser visto como um bug dos locais de GNU libc. Na maioria dos outros sistemas, as localidades garantem que todos os caracteres diferentes tenham ordem de classificação diferente no final. Em localidades GNU, fica ainda pior, pois há milhares de caracteres que não têm uma ordem de classificação e acabam classificando o mesmo, causando todo tipo de problemas (como quebrar comm, join, lsou globs tendo ordens não-deterministas ... ), daí a recomendação de usar LC_ALL=Cpara solucionar esses problemas .

Como observado por @ninjalj nos comentários, o glibc 2.28 lançado em agosto de 2018 veio com algumas melhorias nessa frente do AFAICS, ainda existem alguns caracteres ou elementos de classificação definidos com ordem de classificação idêntica. No Ubuntu 18.10 com glibc 2.28 e em um local en_GB.UTF-8.

$ expr $'L\ub7' = $'L\u387'
1

(por que U + 00B7 seria considerado equivalente a U + 0387 somente quando combinado com L/ l?!).

E:

$ perl -lC -e 'for($i=0; $i<0x110000; $i++) {$i = 0xe000 if $i == 0xd800; print chr($i)}' | sort > all-chars-sorted
$ uniq -d all-chars-sorted | wc -l
4
$ uniq -D all-chars-sorted | wc -l
1061355

(ainda mais de 1 milhão de caracteres (95% do intervalo Unicode, abaixo de 98% em 2.27) classificando da mesma forma que outros caracteres, pois sua ordem de classificação não está definida).

Veja também:


3
Era exatamente isso que eu estava procurando! Para ser completo, o que <PCL>significa? Os outros parecem ser Capital, Minúsculo e Básico?
Draconis

3
@Draconis, confrontando-símbolo <PCL> # 16 particulier / peculiar
Stéphane Chazelas

De fato, se colocarmos um monte de eae ɛamisturados em um arquivo, vemos que sorttodos os tipos são todos eaantes de ɛas.
Bakuriu 27/10/19

2
A partir da glibc 2.28, o ponto de código deve ser usado como substituto para um peso de 4º nível, consulte sourceware.org/git/… sourceware.org/bugzilla/show_bug.cgi?id=14095
ninjalj 27/10/18

11
@cat, desculpe, eu quis dizer strcoll(), veja editar.
Stéphane Chazelas

15

homem classificar:

   ***  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 tente: LC_ALL=C sort file.txt


11
Isso funciona! Mas por que o código do idioma padrão considera esses pontos de código completamente separados iguais? Estou curioso por que isso acontece.
Draconis

@Draconis O que é "a localidade padrão"?
Kamil Maciorowski 26/10

@KamilMaciorowski Um valor vazio da variável de ambiente; Não sei ao que local corresponde.
Draconis

3
O @Draconis, se LC_ALLestiver vazio, sortpode usar outras LC_*variáveis LANGou alguns arquivos de configuração.
NieDzejkob 26/10/19

11
LC_COLLATEé o específico da ordenação por sequência, LANGé o extra-geral.
ShadowRanger 27/10

8

O caractere ɛ não é igual a e, mas algumas localidades podem reunir esses sinais juntos após o agrupamento. A razão para isso é específica da linguagem, mas também alguns antecedentes históricos ou mesmo políticos. Por exemplo, a maioria das pessoas provavelmente espera que a moeda euro se aproxime da Europa no dicionário.

De qualquer forma, para ver qual agrupamento você está usando atualmente locale, locale -aele fornecerá a lista de códigos de idioma disponíveis no sistema e, para alterar o agrupamento, digamos Capenas para uma execução de classificação LC_COLLATE=C sort file. Finalmente, para ver como diferentes localidades podem classificar seu arquivo, tente

for loc in $(locale -a)
    do echo ____"${loc}"____
    LC_COLLATE="$loc" sort file
done

Canalize o resultado para alguma ferramenta de greping para escolher o local que atenda às suas necessidades.


Essa é uma explicação maravilhosa, mas os símbolos parecem ser considerados idênticos, não apenas próximos.
Draconis

11
Não, eles não são considerados idênticos. Adicione uma ealinha simples ao arquivo e, em seguida, sort -uvocê receberá os dois eae ɛaa saída. A melhor estratégia vs. agrupar é evitar ( export LC_COLLATE=C). Caso contrário, muitas coisas feias acontecerão (por exemplo, /tmp/[a-z]in bashcoincidirá /tmp/ae /tmp/Amas não /tmp/Z).
mosvy

@mosvy Huh, interessante ... então eles são considerados iguais para fins de pedidos, mas não para fins de exclusividade?
Draconis

eles não são considerados iguais. veja aqui uma explicação sobre isso.
mosvy

11
@ ninjalj, que pode ser corrigido nos fnmatch()intervalos glibc e regexp, mas não em alguns como bashisso implementa seus intervalos por si só usando strcoll(). O ksh93 nunca teve o problema porque sua implementação de intervalo usa strcoll()e também verifica as maiúsculas e minúsculas dos intervalos e só combina com caracteres minúsculos se as duas extremidades estiverem em minúsculas. Os intervalos zsh não têm o problema, pois são feitos com base no ponto do código, não no strcoll ().
Stéphane Chazelas
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.