【问题标题】:Substring selection with Unicode multibyte characters in Python 3在 Python 3 中使用 Unicode 多字节字符选择子字符串
【发布时间】:2017-06-07 02:08:33
【问题描述】:

我对 Python 3 如何处理 unicode 多字节字符有点困惑。这是一个带有表情符号的示例:

In [1]: print('☺️')
☺️

In [2]: print(len('☺️'))
2

In [3]: print('☺️'[0])
☺

In [4]: print('☺️'[1])
️

In [5]: print(len('????????‍????'))
4

由于我正在从事一个处理表情符号的小型爱好项目,这给我带来了一些问题,因为我更愿意将表情符号作为单个字符串处理,而不是像 Python 3 那样将它们视为多字符串。为什么 Python 3 不能将其识别为单个字符,我该如何以我喜欢的方式处理和使用表情符号?

如果这是我的终端或 REPL 的问题,我正在使用带有 iPython 5.1.0 的 macOS Sierra 终端。

【问题讨论】:

  • ☺️ 使用 UTF-16 方案由 两个 字节表示。
  • @MarounMaroun 当然,但它仍然是单个字符,对吗? UTF-(8|16) 支持多字节字符。
  • @MarounMaroun 这是 UTF-16 中的四个字节。
  • "Unicode multibyte" 用词不当,@Maroun UTF-16 与此无关。 Unicode 单元是代码点(不隐含存储或编码),并且可以使用多个单元来描述单个字符。用于描述一个字符的一系列代码点是一个字素簇
  • 将 Unicode 字符串中的代码点想象成 Python 列表中的数字:[1,2,5000000000]。每个数字有多少字节?答:不在乎。当您真正关心时,就是将数字或 Unicode 字符串写入终端、文件或网络套接字。对于 Unicode 字符串,您将 .encode() 它们转换为字节,指定适当的编码以将代码点转换为一个或多个字节。

标签: python python-3.x unicode emoji


【解决方案1】:

问题是你的两个字符串('☺️'和'??‍?')都包含一个不可见的字符:

>>> '☺️'[0]
'☺'
>>> '☺️'[1]
'️'
>>> '☺️'[1].encode('unicode_escape')
b'\\ufe0f'                             # !!!!!!!!!!
>>> '??‍?'[0]
'?'
>>> '??‍?'[1]
'?'
>>> '??‍?'[2]
'\u200d'                               # !!!!!!!!!!
>>> '??‍?'[3]
'?'

字符'\ufe0f' (U+FE0F) 是Variation Selector-16 代码点

可能会改变前一个字符的外观。如果这是一个符号、dingbat 或表情符号,U+FE0F 会强制将其呈现为彩色图像,而不是单色文本变体。

字符'\u200d' (U+200D) 是Zero Width Joiner

【讨论】:

  • 这很有趣,所以 Python 3 实际上确实从 unicode 的角度正确处理了表情符号;表情符号真的是多字符符号吗?似乎我必须创建一个 String 类的子类来寻找表情符号边缘情况......?
  • 字符,尤其是表情符号,可以由任意数量的代码点组成。这种组的技术术语是字素簇Some examples here. 我认为关于如何迭代那些字素集群有几个问题。
  • regex 3rd 方模块有\X 来匹配字素簇。
  • @JimmyC 表情符号真的是多字符符号吗? 在您的第一个示例中它是,但它不需要。我猜 '\ufe0f' 代码点在您复制时包含在表情符号中。
  • @Leon 我没有复制表情符号,我使用了 macOS 上可用的表情符号键盘。如果不包含 \ufe0f 代码点,☺️ 将变为 ☺。
猜你喜欢
  • 2017-11-19
  • 2012-04-21
  • 1970-01-01
  • 2012-09-20
  • 2012-04-08
  • 2018-04-29
  • 2012-11-30
  • 1970-01-01
相关资源
最近更新 更多