O que é esse caractere: '*'?

48

Um amigo colou um comando em uma sala de bate-papo Slack que continha o caractere * . Isso parece um * normal, mas não é:

$ uniprops '*​'
uniprops: no character named ‹*​›

Enquanto, se eu executar uniprops no asterisco que recebo ao digitar na minha máquina, recebo:

$ uniprops '*'
U+002A ‹*› \N{ASTERISK}
    \pP \p{Po}
    All Any ASCII Assigned Basic_Latin Punct Is_Punctuation Common Zyyy Po P
       Gr_Base Grapheme_Base Graph X_POSIX_Graph GrBase Other_Punctuation
       Pat_Syn Pattern_Syntax PatSyn POSIX_Graph POSIX_Print POSIX_Punct Print
       X_POSIX_Print Punctuation Unicode X_POSIX_Punct

Também posso ver que não é um asterisco real passando od :

$ printf '*​' | od -c
0000000   * 342 200 213
0000004

Enquanto o normal dá:

$ printf '*' | od -c
0000000   *
0000001

Aqui está o personagem misterioso um pouco maior:

*

E o asterisco normal (sim, eles parecem idênticos):

*

Então, uniprops não sabe o que é isso, e também não consigo encontrá-lo no link . Eu sei que o amigo que colou é no OS X (eu estou no Linux) e que funciona em seu sistema como um asterisco regular. Estou assumindo que o Slack de alguma forma mudou isso. Então, alguém tem alguma ideia do que esse personagem é?

Observe que você não pode copiar o caractere estranho diretamente da pergunta. Aparentemente, o mecanismo do Stack Exchange remove os caracteres de não-impressão à direita. Clique no link "editar" e copie a partir daí.

uniprops é um pequeno script completo incluído no módulo Unicode::Tussle Perl que identifica e imprime informações sobre o caractere que você fornece.

    
por terdon 20.07.2016 / 11:59

2 respostas

71

A colagem falhou não por causa do asterisco, que é um asterisco perfeitamente regular, mas por causa do Caractere Unicode U + 200B . Como o caractere é um ZERO WIDTH SPACE , ele não é exibido quando é copiado.

Usando o código Python:

stro=u"'*​'?"
def uniconv(text):
    return " ".join(hex(ord(char)) for char in text)
uniconv(stro)

A função uniconv converte a cadeia de entrada (nesse caso, u"'*'?" ) em seus equivalentes da página de códigos Unicode em formato hexadecimal. O prefixo u para a string identifica a string como uma string Unicode.

Consegui obter a saída:

0x27 0x2a 0x200b 0x27 0x3f

Podemos ver claramente que 0x27 , 0x2a e 0x3f são os valores hexadecimais ASCII / Unicode para os caracteres ' , * e ? , respectivamente. Isso deixa 0x200b , portanto identificando o personagem.

Observe que o código Python, quando colado no corpo, teve o caractere U + 200B removido pelo software Markdown da SE. Para obter o resultado esperado, você precisa copiá-lo diretamente do título usando a visualização Editar.

    
por 20.07.2016 / 12:16
27

Com a ajuda de @Rinzwind na sala de bate-papo do Ask Ubuntu, descobri que o problema não é o caractere. Observe a saída de od :

$ printf '*​' | od -c
0000000   * 342 200 213
0000004

O 342 200 213 é uma representação octal de outro caractere e podemos usar este site para pesquisar:

Character                   ​               
Character name                              ZERO WIDTH SPACE
Hex code point                              200B
Decimal code point                          8203
Hex UTF-8 bytes                             E2 80 8B
Octal UTF-8 bytes                           342 200 213
UTF-8 bytes as Latin-1 characters bytes     â <80> <8B>

Então, o que eu realmente tive foram dois caracteres unicode, o% normal* e um espaço de largura zero.

    
por 20.07.2016 / 12:20