Qual é esse personagem: '*'?

48

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

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

Embora se eu rodar unipropsno 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 por 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):

*

Portanto, unipropsnão sei o que é isso, e também não consigo encontrá-lo em http://www.fileformat.info/ . Eu sei que o amigo que o colou está no OS X (eu estou no Linux) e que funciona no sistema deles como um asterisco regular. Estou assumindo que o Slack mudou de alguma forma. Então, alguém tem alguma idéia do que esse personagem é?

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


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

Terdon
fonte
Não pode se reproduzir. Eu usei ord("*")sua string colada e a *chave nativa e obtive o mesmo número para ambas (42).
Ho Ho
7
@MarchHo caramba, o mecanismo SE parece estar comendo isso. Testei antes da postagem e pude copiar o caractere estranho (embora esteja começando a entender que o problema é que foram adicionados caracteres extras não imprimíveis), mas também não consigo copiar da pergunta postada. Você precisa clicar no link de edição e copiar a partir daí.
terdon 20/07/16
2
Estranhamente, no aplicativo Android, o zero com espaço é exibido como se fosse um espaço normal.
21416 derobert
11
Curiosamente, quando colo de 'edit' no meu terminal urxvt, ele já é exibido como *<200b>.
bodo 21/07
Se você copiá-lo da sua seção de código, por exemplo, a linha uniprops, ele copia OK sem precisar ir para a fonte da pergunta. (Colá-lo no intérprete Python3 '*\u200b'também é exibido )
TessellatingHeckler

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 é a 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 uniconvconverte a sequência de entrada (nesse caso u"'*'?") em seus equivalentes de página de código Unicode no formato hexadecimal. O uprefixo da sequência identifica a sequência como uma sequência Unicode.

Consegui obter a saída:

0x27 0x2a 0x200b 0x27 0x3f

Podemos ver claramente que 0x27, 0x2ae 0x3fsão os / valores ASCII Unicode hexadecimais para os personagens ', *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, é necessário copiá-lo diretamente do título usando a visualização Editar.

March Ho
fonte
5
Substituir strpor hexproduzirá os pontos de código em hexadecimal, facilitando o reconhecimento ou a pesquisa.
Deltab
Há também um módulo dedicado python chamado unicodedata, com o qual você pode consultar os nomes dos personagens, categoria etc.
bodo
4
Os caracteres ZERO WIDTH SPACE e ZERO WIDTH JOINER são úteis para sistemas de comentários que tentam bloquear termos comuns de spam. Por exemplo, para salientar que Bernie Sanders foi eleito para o Senado como Socialista (sem tropeçar em uma armadilha de spam para "Cialis"), escreva-o como "Soci & zwj; alist" se as Entidades HTML forem respeitadas ou cole no personagem do Mapa de Caracteres ou equivalente, se não forem.
Monty mais dura
27

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

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

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

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, na verdade, eu tinha dois caracteres unicode, o normal *e o espaço de largura zero.

Terdon
fonte
6
Outra maneira de fazer isso é printf '\342\200\213' | uniname. (uniname é a partir do pacote uniutils.)
deltab
11
A partir deste site você pode ter conversões de formato diferentes: para HEX dá 002A 200B, para utf-8 2A E2 80 8Bpara utf-16 002A 200B...
Hastur