Что это за символ: '*'?


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


Не могу воспроизвести. Я использовал ord("*")для вашей вставленной строки и нативный *ключ, и получил одинаковое число для обоих (42).
Март Хо,

7
@ МарчО, черт возьми, движок SE, похоже, его съел. Я проверял перед публикацией и мог скопировать странный символ (хотя я начинаю понимать, что проблема в том, что там были добавлены дополнительные непечатные символы), но я также не могу скопировать из опубликованного вопроса. Вам нужно нажать на ссылку для редактирования и скопировать оттуда.
Тердон

2
Как ни странно, в приложении для Android ноль с пробелом отображается так, как если бы это был обычный пробел.
Дероберт

1
Интересно, что когда я вставляю из «edit» в свой терминал urxvt, он уже отображается как *<200b>.
Бодо

Если вы скопируете его из своего раздела кода, например, из строки uniprops, он скопирует OK без необходимости перехода к источнику вопроса. (Вставка его в интерпретатор Python3 показывает '*\u200b'тоже самое)
TessellatingHeckler

Ответы:


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Префикс к строке идентифицирует строку в виде строки Unicode.

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

0x27 0x2a 0x200b 0x27 0x3f

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

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


5
Замена strна hexбудет выводить кодовые точки в шестнадцатеричном формате, что облегчает их распознавание или поиск.
Deltab

Существует также специальный модуль python unicodedata, с помощью которого вы можете запрашивать имена персонажей, категории и т. Д.
бодло

4
Символы ZERO WIDTH SPACE и ZERO WIDTH JOINER удобны для использования с системами комментариев, которые пытаются блокировать распространенные термины спама. Например, чтобы указать, что Берни Сандерс был избран в Сенат социалистом (без использования спам-ловушки для «Сиалиса»), напишите его как «Soci & zwj; alist», если соблюдаются HTML-сущности, или вставьте символ из карты персонажей. или эквивалент, если они не.
Монти Хардер

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>

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


6
Еще один способ сделать это printf '\342\200\213' | uniname. (uniname из пакета uniutils.)
deltab

1
С этого сайта вы можете иметь различные преобразования формата: для HEX это дает 002A 200B, для utf-8 2A E2 80 8Bдля utf-16 002A 200B...
Hastur
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.