【问题标题】:Python 2.7: Names of unicode representationsPython 2.7:Unicode 表示的名称
【发布时间】:2018-03-22 09:31:40
【问题描述】:

这些不同类型的 unicode ASCII 表示形式的名称是什么?

  • \xF0\x9F\x98\xA2
  • \U0001f622

对于他们所属的集合,有没有比“表示”更具体的术语?在这些情况下,我将如何描述非 ascii 表示(????)?

由于我不知道如何称呼它们,因此很难搜索如何使用它们。

谢谢!

【问题讨论】:

  • 这似乎是一个特定于语言的问题,或者至少会有特定于语言的答案。此外,在允许使用十六进制字节格式的情况下,字节不会被解释为 Unicode。例如,在 C# 中不允许。在 JavaScript 中,它表示来自 ISO 8859-1 的字节,然后作为 Unicode 字符放入字符串中。

标签: python unicode utf-8 unicode-escapes unicode-literals


【解决方案1】:

对于 Python 3

首先似乎对十六进制转义存在误解:

print("\xF0\x9F\x98\xA2" == "\u00F0\u009F\u0098\u00A2")
print("\xF0\x9F\x98\xA2" == "\U000000F0\U0000009F\U00000098\U000000A2")
print("\xF0\x9F\x98\xA2" == "\U000000F0\U0000009F\U00000098\U000000A2")
print("\xF0\x9F\x98\xA2" == "\N{LATIN SMALL LETTER ETH}\N{APPLICATION PROGRAM COMMAND}\N{START OF STRING}\N{CENT SIGN}")

为了完整性(我记得在机器代码中有效地使用八进制,其中一些指令具有 3 位对齐的参数,但我在实际编程中看不到重点):

print("\xF0\x9F\x98\xA2" == "\360\237\230\242")

看来它们都是 Unicode codepoint 以 2 位十六进制、4 位十六进制和 8 位十六进制转义,范围从 U+0000 到 U+00FF、U+FFFF、和 U+10FFFF,分别。

我们可以确认,与 \u 表示 UTF-16 代码单元的其他语言不同,在 Python 3 中,它实际上是一个代码点。

print("\ud83d\ude22" == "\U0000d83d\U0000de22")

为了完整性:

print("\U0001f622" == "?")
print("\N{CRYING FACE}" == "?")

在其他语言中(它们是两个 UTF-16 代码单元),"\ud83d\ude22" 等于 "?"

现在,U+D8ED 和 U+DE22 是指定为代理的 Unicode 代码点。换句话说,不是字符。它们为具有相应值的 UTF-16 代码单元保留代码点代码空间。当 Unicode 从 2^16 个码点扩展到 2^21 个码点时,这就是 Unicode 的 USC-2 编码透明地扩展到 UTF-16 的方式。如需更多信息,请参阅Unicode FAQ


正如@Robᵩ 指出的那样,你也可以有一个字节串文字:

print("\U0001f622".encode("utf-8") == b"\xF0\x9F\x98\xA2")

【讨论】:

  • \u 的处理方式可能取决于您使用的 Python 版本和构建。对我来说,u"\ud83d\ude22" == u'\U0001f622' 在 2.7 上产生 True 但在 3.6 上产生 False
【解决方案2】:

正如 Tom Blodget 已经警告过你的那样,这是一个特定于 python 的答案。


前导\ 表明它是一个转义序列。

\x 表示接下来的两个字符将被解释为十六进制数字。

\U 表示接下来的八个字符将被解释为 32 位十六进制值。

您可以在此处阅读更多相关信息:

https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals

完整回答您的问题:

  • \xF0\x9F\x98\xA2 只是四个 ASCII 字符,你有它们的十六进制值
  • \U0001f622 是使用 32 位十六进制值编码的 UNICODE 代码点
  • ? 是一个字形或只是一个特殊字符。

【讨论】:

  • 第一个也是第二个的UTF-8编码。
  • \x00\x7f 范围之外的十六进制值不是 ASCII。这不是 16 位十六进制值,而是 32 位。技术术语是“代码点”,而不是“字符”。
  • 是的,我将十六进制值与十六进制数字混淆了。 8个十六进制数字表示32位,你是对的,我编辑了答案。
  • @MarkRansom 你的意思是这个答案中的第二个要点应该是 "\U0001f622 is a UNICODE codepoint" 吗?
  • @NathanHinchey 完全正确。
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-22
  • 2018-09-28
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多