web-dev-qa-db-fra.com

Quel est ce personnage: '*'?

Un ami a collé une commande dans une salle de discussion Slack contenant le caractère *. Cela ressemble à un * normal mais ne l'est pas:

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

Alors que si je lance uniprops sur l'astérisque que je reçois en tapant sur ma machine, je reçois:

$ 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

Je peux aussi voir que ce n'est pas un astérisque réel en le passant par od:

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

Alors que la normale donne:

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

Voici le personnage mystère un peu plus grand:

*

Et l'astérisque normal (oui, ils ont l'air identique):

*

Donc, uniprops ne sait pas ce que c'est et je ne le trouve pas non plus sur http://www.fileformat.info/ Je sais que l'ami qui l'a collé est sous OS X (je suis sous Linux) et que cela fonctionne sur son système comme un astérisque normal. Je suppose que Slack l'a changé d'une manière ou d'une autre. Alors, est-ce que quelqu'un a une idée de ce que ce personnage est?

Notez que vous ne pouvez pas copier le caractère étrange directement à partir de la question. Apparemment, le moteur Stack Exchange supprime les derniers caractères non imprimables. Cliquez sur le lien "modifier" et copiez-le à partir de là.


uniprops est un petit script soigné inclus dans le module Perl Unicode::Tussle qui identifie et affiche des informations sur le caractère que vous lui donnez.

48
terdon

Le collage a échoué non pas à cause de l'astérisque, qui est un astérisque parfaitement normal, mais à cause du caractère Unicode U + 200B . Comme le caractère est un ZERO WIDTH SPACE, il ne s’affiche pas lorsqu’il est copié.

En utilisant le code Python:

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

La fonction uniconv convertit la chaîne d'entrée (dans ce cas, u"'*'?") en leurs équivalents page de code Unicode au format hexadécimal. Le préfixe u de la chaîne identifie la chaîne en tant que chaîne Unicode.

J'ai pu obtenir le résultat:

0x27 0x2a 0x200b 0x27 0x3f

Nous pouvons clairement voir que 0x27, 0x2a et 0x3f sont les valeurs hexadécimales ASCII/Unicode pour les caractères ', * et ? respectivement. Cela laisse 0x200b, identifiant donc le caractère.

Notez que le code Python, une fois collé dans le corps, avait le caractère U + 200B supprimé par le logiciel Markdown de SE. Pour obtenir le résultat attendu, vous devez le copier directement à partir du titre à l'aide de la vue Modifier.

71
March Ho

Avec l'aide de @Rinzwind dans la salle de discussion Ask Ubuntu, j'ai compris que le problème ne venait pas du personnage. Notez le résultat de od:

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

Le 342 200 213 est une représentation octale d'un autre caractère et nous pouvons utiliser ce site pour le rechercher:

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>

Donc, ce que j’avais réellement, c’était deux caractères unicode, le * normal et un espace de largeur zéro.

27
terdon