这个字符是什么:'*?'?

ter*_*don 48 unicode special-characters

一位朋友将命令粘贴到包含该字符的Slack聊天室中*。这看起来很正常,*但不是:

$ uniprops '*?'
uniprops: no character named ‹*?›
Run Code Online (Sandbox Code Playgroud)

而如果我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
Run Code Online (Sandbox Code Playgroud)

通过传递它,我还可以看到它不是实际的星号od

$ printf '*?' | od -c
0000000   * 342 200 213
0000004
Run Code Online (Sandbox Code Playgroud)

而正常的给出:

$ printf '*' | od -c
0000000   *
0000001
Run Code Online (Sandbox Code Playgroud)

这是一个更大的神秘角色:

*?

和正常的星号(是的,它们看起来确实相同):

*

所以,uniprops不知道这是什么,我也无法在http://www.fileformat.info/上找到它。我确实知道粘贴它的朋友在 OS X 上(我在 Linux 上)并且它在他们的系统上作为常规星号运行。我假设 Slack 以某种方式改变了它。那么,有没有人知道这个角色是什么?

请注意,您不能直接从问题中复制奇怪的字符。显然,Stack Exchange 引擎会去除尾随的非打印字符。单击“编辑”链接并从那里复制。


uniprops是包含在Unicode::TusslePerl 模块中的一个简洁的小脚本,它识别并打印有关您给它的字符的信息。

Mar*_* Ho 71

粘贴失败不是因为星号,这是一个非常规则的星号,而是因为Unicode 字符 U+200B。由于字符是ZERO WIDTH SPACE,所以复制时不显示。

使用 Python 代码:

stro=u"'*?'?"
def uniconv(text):
    return " ".join(hex(ord(char)) for char in text)
uniconv(stro)
Run Code Online (Sandbox Code Playgroud)

该函数uniconv将输入字符串(在本例中为u"'*'?")转换为十六进制格式的 Unicode 代码页等效项。u字符串的前缀将字符串标识为 Unicode 字符串。

我能够获得输出:

0x27 0x2a 0x200b 0x27 0x3f
Run Code Online (Sandbox Code Playgroud)

我们可以清楚地看到0x27,0x2a0x3f分别是字符 的 ASCII/Unicode 十六进制值',*?。那留下0x200b,因此识别字符。

请注意,将 Python 代码粘贴到正文中时,SE 的 Markdown 软件删除了 U+200B 字符。为了获得预期的结果,您需要使用编辑视图直接从标题中复制它。

  • 用 `hex` 替换 `str` 将以十六进制输出代码点,使它们更容易识别或查找。 (5认同)
  • ZERO WIDTH SPACE 和 ZERO WIDTH JOINER 字符可方便地与试图阻止常见垃圾邮件术语的评论系统一起使用。例如,要指出伯尼桑德斯作为社会主义者被选入参议院(没有为“Cialis”设置垃圾邮件陷阱),如果 HTML 实体受到尊重,则将其写为“Soci‍alist”,或粘贴字符映射中的字符或者等价的,如果不是的话。 (4认同)

ter*_*don 27

在 Ask Ubuntu 聊天室中 @Rinzwind 的帮助下,我发现问题根本不在于角色。注意输出od

$ printf '*?' | od -c
0000000   * 342 200 213
0000004
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

所以,我实际上拥有的是两个 unicode 字符,一个正常的*和一个零宽度的空间。

  • 另一种方法是 `printf '\342\200\213' | 单名`。(uniname 来自 uniutils 包。) (6认同)