一位朋友将命令粘贴到松弛聊天室中包含角色*
。这看起来像是正常的*
,但实际上不是:
$ 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 上),并且它在他们的系统上可以像普通星号一样工作。我猜 Slack 以某种方式改变了它。那么,有人知道那个字符是什么吗?
请注意,您不能直接从问题中复制奇怪的字符。显然,Stack Exchange 引擎会删除尾随的非打印字符。单击“编辑”链接并从那里复制。
uniprops
是 Perl 模块中包含的一个简洁的小脚本Unicode::Tussle
,它可以识别并打印有关您指定的字符的信息。
答案1
粘贴失败的原因不是星号(星号非常规则),而是因为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 代码粘贴到正文中时,SE 的 Markdown 软件会删除 U+200B 字符。为了获得预期结果,您需要使用编辑视图直接从标题中复制它。
答案2
在 Ask Ubuntu 聊天室中 @Rinzwind 的帮助下,我发现问题根本不是字符。请注意 的输出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字符,一个是普通字符*
,另一个是零宽度空格。