【问题标题】:Python length of unicode string confusionPython长度的unicode字符串混淆
【发布时间】:2015-06-11 08:37:45
【问题描述】:

已经有很多帮助,但我仍然很困惑。

我有一个这样的 unicode 字符串:

title = u'????test'
title_length = len(title) #5

但是!我需要 len(title) 为 6。客户希望它为 6,因为他们的计数方式似乎与我在后端的计算方式不同。

作为一种解决方法,我编写了这个小助手,但我确信它可以改进(对编码有足够的了解),或者它甚至可能是错误的。

title_length = len(title) + repr(title).count('\\U') #6

1.有没有更好的方法让长度为 6? :-)

我假设我(Python)正在计算 unicode 字符的数量,即 5。客户端正在计算字节数?

2。对于其他需要 4 个字节的 unicode 字符,我的逻辑会中断吗?

运行 Python 2.7 ucs4。

【问题讨论】:

  • 客户端统计 UTF-16 代理对。
  • 当我尝试运行这两行时,它显示的长度为 6。
  • @ssundarraj:看我的回答;您正在运行 Python 2 UCS2 构建。使用 Python 3.3 或更高版本,或者自己构建 UCS4。

标签: python unicode


【解决方案1】:

您有 5 个代码点。其中一个代码点位于 Basic Multilingual Plane 之外,这意味着这些代码点 has to use two code units for the character 的 UTF-16 编码。

换句话说,客户端依赖于一个实现细节,并且做错了什么。他们应该计算代码,而不是代码单位。有几个平台经常发生这种情况; Python 2 UCS2 构建就是其中之一,但 Java 开发人员经常忘记区别,Windows API 也是如此。

您可以将文本编码为 UTF-16 并将字节数除以 2(每个 UTF-16 代码单元为 2 个字节)。选择 utf-16-leutf-16-be 变体以在长度中不包含 BOM

title = u'?test'
len_in_codeunits = len(title.encode('utf-16-le')) // 2

如果您使用的是 Python 2(并根据您可能使用的字符串的 u 前缀判断),请考虑到 Python 有两种不同的风格,具体取决于您构建它的方式。根据构建时配置开关,您将拥有 UCS-2 或 UCS-4 构建;前者在 internally 中也使用了代理项,并且您的 title 值长度也将是 6。见Python returns length of 2 for single Unicode character string

【讨论】:

  • 客户端确实是 Java,你怎么知道他们在计算 UTF-16 代理对?难道它也不能是 UTF-8 或 UTF-32 吗?我可以确定他们总是计算 2 个代码单元,取决于代码点可能更多吗?你的计数方法看起来确实更优雅。 :-) 非常感谢您的精彩解释!
  • 如果他们在不同的 UTF 编解码器中计算代码单元(UTF-8 中为 8,UTF-32 中为 5),则计数会大不相同。是的,UTF-16 总是使用一个或两个代码单元,请参阅我的答案中的 Wikipedia 链接。 Java代码可以固定;见JSR-204codePointCount() method
猜你喜欢
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
  • 2013-04-03
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多