Quel est ce personnage: '*'?

48

Un ami a collé une commande dans une salle de discussion Slack contenant le personnage *. Cela ressemble à une normale *mais n'est pas:

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

Tandis que si je cours unipropssur 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 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, unipropsje ne sais 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 à partir de là.


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

terdon
la source
Ne peut pas reproduire. J'ai utilisé ord("*")pour votre chaîne collée et la *clé native , et j'ai obtenu le même numéro pour les deux (42).
Mars Ho
7
@MarchHo putain, le moteur SE semble le manger. J'ai testé avant de poster et pouvais copier le caractère étrange (bien que je commence à comprendre que le problème est qu'il y avait des caractères supplémentaires non imprimables ajoutés ici) mais je ne peux pas copier la question postée non plus. Vous devez cliquer sur le lien modifier et copier à partir de là.
Terdon
2
Bizarrement, sur l’application Android, le zéro avec espace s’affiche comme s’il s’agissait d’un espace normal.
Derobert
1
Fait intéressant, lorsque je colle de «modifier» dans mon terminal urxvt, il est déjà affiché comme *<200b>.
Bodo
Si vous le copiez à partir de votre section de code, par exemple la ligne uniprops, la copie sera OK sans avoir à passer à la source de la question. (Coller dans Python3 interprète montre comme '*\u200b'aussi)
TessellatingHeckler

Réponses:

71

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 uniconvconvertit la chaîne d'entrée (dans ce cas, u"'*'?") en leurs équivalents page de code Unicode au format hexadécimal. Le upréfixe 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

On voit bien que 0x27, 0x2aet 0x3fsont les valeurs hexadécimal ASCII / Unicode pour les caractères ', *et ?respectivement. Cela laisse 0x200bdonc identifier le personnage.

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.

March Ho
la source
5
Remplacer strpar hexaffichera les points de code en hexadécimal, ce qui les rendra plus faciles à reconnaître ou à rechercher.
Deltab
Il existe également un module dédié appelé python unicodedata, avec lequel vous pouvez interroger les noms de caractères, la catégorie, etc.
bodo
4
Les caractères ZERO WIDTH SPACE et ZERO WIDTH JOINER sont pratiques à utiliser avec les systèmes de commentaires qui tentent de bloquer les termes de spam courants. Par exemple, pour signaler que Bernie Sanders a été élu au Sénat en tant que socialiste (sans déclencher un spam spam pour "Cialis"), écrivez-le en tant que "Société" si les entités HTML sont respectées, ou collez le caractère dans Character Map. ou équivalent s'ils ne le sont pas.
Monty Harder
27

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

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

Le 342 200 213est une représentation octale d’un autre personnage 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, l’ *espace normal et un espace nul.

terdon
la source
6
Une autre façon de faire est printf '\342\200\213' | uniname. (Uniname est issu du paquet uniutils.)
deltab le
1
À partir de ce site, vous pouvez avoir différents formats de conversion: pour HEX cela donne 002A 200B, pour utf-8 2A E2 80 8Bpour utf-16 002A 200B...
Hastur