¿Cuál es este personaje: '*'?

48

Un amigo pegó un comando en una sala de chat Slack que contenía al personaje *. Esto parece normal *pero no lo es:

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

Mientras que si ejecuto unipropsel asterisco que obtengo al escribir en mi máquina, obtengo:

$ 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

También puedo ver que no es un asterisco real al pasarlo od:

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

Mientras que el normal da:

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

Aquí está el personaje misterioso un poco más grande:

* *

Y el asterisco normal (sí, se ven idénticos):

* *

Entonces, unipropsno sabe qué es esto, y tampoco puedo encontrarlo en http://www.fileformat.info/ . Sé que el amigo que lo pegó está en OS X (estoy en Linux) y que funciona en su sistema como un asterisco normal. Supongo que Slack de alguna manera lo cambió. Entonces, ¿alguien tiene alguna idea de cuál es ese personaje?

Tenga en cuenta que no puede copiar el personaje extraño directamente de la pregunta. Aparentemente, el motor de Stack Exchange elimina los caracteres finales que no se imprimen. Haga clic en el enlace "editar" y copie desde allí en su lugar.


unipropses un pequeño script ordenado incluido en el Unicode::Tusslemódulo Perl que identifica e imprime información sobre el personaje que le das.

terdon
fuente
No puede reproducir. Utilicé ord("*")su cadena pegada y la *clave nativa , y obtuve el mismo número para ambos (42).
Marzo Ho
77
@MarchHo maldita sea, el motor SE parece estar comiéndolo. Probé antes de publicar y pude copiar el personaje extraño (aunque, estoy empezando a entender que el problema es que se agregaron caracteres adicionales que no se imprimen allí) pero tampoco puedo copiar de la pregunta publicada. Debe hacer clic en el enlace de edición y copiar desde allí.
terdon
2
Curiosamente, en la aplicación de Android, el cero con espacio se muestra como si fuera un espacio normal.
derobert
1
Curiosamente, cuando pego desde 'editar' en mi terminal urxvt, ya se muestra como *<200b>.
bodo
Si lo copia de su sección de código, por ejemplo, la línea uniprops, entonces copia OK sin necesidad de ir al origen de la pregunta. (Al pegarlo en Python3, el intérprete también se muestra '*\u200b')
TessellatingHeckler

Respuestas:

71

La pasta falló no por el asterisco, que es un asterisco perfectamente regular, sino por el carácter Unicode U + 200B . Como el carácter es un ZERO WIDTH SPACE, no se muestra cuando se copia.

Usando el código Python:

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

La función uniconvconvierte la cadena de entrada (en este caso u"'*'?") en sus equivalentes de página de códigos Unicode en formato hexadecimal. El uprefijo de la cadena identifica la cadena como una cadena Unicode.

Pude obtener la salida:

0x27 0x2a 0x200b 0x27 0x3f

Podemos ver claramente eso 0x27, 0x2ay 0x3fson los valores hexadecimales ASCII / Unicode para los caracteres ', *y ?respectivamente. Eso deja 0x200b, por lo tanto, la identificación del personaje.

Tenga en cuenta que el código Python, cuando se pega en el cuerpo, tenía el carácter U + 200B eliminado por el software Markdown de SE. Para obtener el resultado esperado, debe copiarlo directamente desde el título utilizando la vista Editar.

March Ho
fuente
55
Reemplazar strcon hexgenerará los puntos de código en hexadecimal, haciéndolos más fáciles de reconocer o buscar.
deltab
También hay un módulo dedicado de Python llamado unicodedata, con el que puede consultar los nombres de los personajes, la categoría, etc.
bodo
44
Los caracteres ZERO WIDTH SPACE y ZERO WIDTH JOINER son útiles para usar con sistemas de comentarios que intentan bloquear términos comunes de spam. Por ejemplo, para señalar que Bernie Sanders fue elegido al Senado como socialista (sin tropezar con una trampa de spam para "Cialis") escríbalo como "Soci & zwj; alist" si se respetan las Entidades HTML, o pegue el carácter del Mapa de caracteres o equivalente si no lo son.
Monty Harder
27

Con la ayuda de @Rinzwind en la sala de chat Ask Ubuntu, descubrí que el problema no es el personaje en absoluto. Tenga en cuenta la salida de od:

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

El 342 200 213es una representación octal de otro personaje y podemos usar este sitio para buscarlo:

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>

Entonces, lo que realmente tenía eran dos caracteres unicode, el *espacio normal y un espacio de ancho cero.

terdon
fuente
66
Otra forma de hacerlo es printf '\342\200\213' | uniname. (Uniname es del paquete Uniutils)
Deltab
1
Desde este sitio puede tener conversiones de diferentes formatos: para HEX da 002A 200B, para utf-8 2A E2 80 8Bpara utf-16 002A 200B...
Hastur