Що це за персонаж: '*'?


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).
Ho March

7
@MarchHo чорт, двигун SE, здається, їсть його. Я тестував перед публікацією і міг скопіювати дивний символ (хоча, я починаю розуміти, що проблема полягає в тому, що там були додані зайві недрукарські символи), але я також не можу копіювати з розміщеного запитання. Потрібно натиснути на посилання для редагування та скопіювати звідти.
тердон

2
Як не дивно, в додатку Android нуль з пробілом відображається так, ніби це був звичайний пробіл.
derobert

1
Цікаво, що коли я вставляю з "редагування" у свій термінал urxvt, він вже відображається як *<200b>.
BODO

Якщо ви копіюєте його з кодового розділу, наприклад, рядок uniprops, він копіює ОК, не потребуючи переходу до джерела запитань. (Вставлення його до інтерпретатора Python3 також показує '*\u200b')
TessellingHeckler

Відповіді:


71

Паста вийшла з ладу не через зірочку, яка є абсолютно регулярною зірочкою, а через символ Unicode U + 200B . Оскільки символ є a 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 видалявся за допомогою програмного забезпечення Markdown SE. Для отримання очікуваного результату потрібно скопіювати його безпосередньо з заголовка за допомогою перегляду Правка.


5
Заміна strна hexвиводить кодові точки в шістнадцятковий, полегшуючи їх розпізнавання або пошук.
дельтаб

Існує також спеціальний модуль пітона називається unicodedata, з допомогою якого ви можете запросити імена персонажів, категорія і т.д.
Бодо

4
Персонажі ZERO WIDTH SPACE та ZERO WIDTH JOINER зручно використовувати в системах коментарів, які намагаються блокувати загальні умови для спаму. Наприклад, щоб зазначити, що Берні Сандерс був обраний до Сенату соціалістом (без вимкнення пастки спаму для "Cialis"), напишіть його як "Soci & zwj; alist", якщо дотримуються HTML Суб'єкти, або вставте символ із карти символів або еквівалент, якщо їх немає.
Monty Harder

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>

Отже, у мене насправді було два символи unicode, нормальний *та нульовий простір.


6
Ще один спосіб зробити це printf '\342\200\213' | uniname. (uniname - з пакету
uniutils

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.