48

Друг вставил в чат комнату Slack команду, в которой был символ * . Это выглядит как обычный * но не так:

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

Хотя, если я запускаю uniprops на звездочке, которую получаю при наборе текста на моей машине, я получаю:

$ 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

Я также вижу, что это не настоящая звездочка, передав ее через od:

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

В то время как нормальный дает:

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

Вот загадочный персонаж немного больше:

*

И обычная звездочка (да, они выглядят одинаково):

*

Таким образом, uniprops не знает, что это такое, и я не могу найти его на http://www.fileformat.info/ . Я знаю, что друг, который вставил его, находится на OS X (я на Linux) и что он работает в их системе как обычная звездочка. Я предполагаю, что Слэк как-то изменил это. Итак, кто-нибудь знает, что это за персонаж?

Обратите внимание, что вы не можете скопировать странный символ непосредственно из вопроса. По-видимому, механизм Stack Exchange удаляет конечные непечатаемые символы. Нажмите на ссылку "Изменить" и скопируйте оттуда.


uniprops - это аккуратный маленький скрипт, включенный в модуль Perl Unicode::Tussle который идентифицирует и печатает информацию о персонаже, которого вы ему даете.

2 ответа2

71

Ошибка вставки произошла не из-за звездочки, которая является совершенно обычной звездочкой, а из-за символа Unicode U+200B. Поскольку символ является ZERO WIDTH SPACE , он не отображается при копировании.

Используя код Python:

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

Функция uniconv преобразует входную строку (в данном случае, u"'*'?") в их эквиваленты кодировки Unicode в шестнадцатеричном формате. Префикс u к строке идентифицирует строку как строку Юникода.

Я был в состоянии получить вывод:

0x27 0x2a 0x200b 0x27 0x3f

Мы можем ясно видеть, что 0x27 , 0x2a и 0x3f являются шестнадцатеричными значениями ASCII/Unicode для символов ' , * и ? соответственно. Это оставляет 0x200b , поэтому идентифицирует персонажа.

Обратите внимание, что в коде Python, вставленном в тело, символ U+200B был удален программным обеспечением SE Markdown. Чтобы получить ожидаемый результат, вам необходимо скопировать его непосредственно из заголовка, используя представление «Изменить».

27

С помощью @Rinzwind в чате Ask Ubuntu я понял, что проблема вовсе не в персонаже. Обратите внимание на вывод od:

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

342 200 213 является восьмеричным представлением другого символа, и мы можем использовать этот сайт, чтобы найти его:

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>

Итак, у меня на самом деле были два символа Юникод, нормальный * и пробел нулевой ширины.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .