python - 不同的 Unicode 字符串编码相同

标签 python python-2.7 unicode encoding utf-8

我有两个 unicode 字符串,即使在标准化之后它们也不同。但是,当编码为 UTF-8 时,它们是相同的。我想了解它们有何不同(也许为什么)。

它们都是实体的标识符,查找失败是因为标识符错误,但是作为字节字符串,它们是相同的,所以我想了解我们如何可能得到不同的 unicode 字符串(它们已经由不同的子系统处理)以及我如何判断它们实际上是相同的。

“\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\U0002ae18\U00025314\u30c3”

和:

"\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\ud86b\ude18\ud854\udf14\u30c3"

问题似乎不是标准化问题。我意识到这个问题的要素是无法回答的,但我将不胜感激任何线索!

>>> a = u"\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\ud86b\ude18\ud854\udf14\u30c3"
>>> b = u"\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\U0002ae18\U00025314\u30c3"
>>> a == b
False
>>> import unicodedata
>>> unicodedata.normalize('NFKD', a) == unicodedata.normalize('NFKD', b)
False
>>> a.encode('UTF-8') == b.encode('UTF-8')
True

最佳答案

我不确定您是如何得到结果的。在 Python 2.7 中,您的 ab Unicode 字符串是相同的:

    >>> a = u"\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\ud86b\ude18\ud854\udf14\u30c3"
    >>> b = u"\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\U0002ae18\U00025314\u30c3"
    >>> a == b
    True
    >>> a
    u'\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\U0002ae18\U00025314\u30c3'
    >>> b
    u'\u8a92\u6089\u5bfd\u4267\ucdb7\u5727\u4039\U0002ae18\U00025314\u30c3'

Python 2.7 在内部使用 UTF-16LE 来存储 Unicode 字符串。 U+FFFF 以上的代码点使用代理项(两个 16 位代码单元)存储。请注意它们如何显示相同,即使输入不同。这两个字符串在内部以相同的方式解析和存储。另一个例子:

>>> s = u'\U00025314'
>>> len(s)
2
>>> hex(ord(s[0]))
'0xd854'
>>> hex(ord(s[1]))
'0xdf14'
>>> s = u'\ud854\udf14'
>>> s
u'\U00025314'

在 Python 3.3+ 中 leaky abstraction暴露 Unicode 如何在内部存储的实现细节已得到修复:

>>> # python 3.3+
>>> s = '\U00025314'
>>> len(s)
1
>>> hex(ord(s[0]))
>>> hex(ord(s[0]))
'0x25314'
>>> s.encode('utf8')
b'\xf0\xa5\x8c\x94'

>>> s = '\ud854\udf14'
>>> s
'\ud854\udf14'
>>> s.encode('utf8')
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
UnicodeEncodeError: 'utf-8' codec can't encode characters in position 0-1: surrogates not allowed

关于python - 不同的 Unicode 字符串编码相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47791990/

相关文章:

python - 不能 Pickle memoize 类实例

python - 如何处理 requests_futures 的速率限制?

c# - 将 ASCII 字符数组转换为 UNICODE 字符串

python - 如何在Python中将unicode代码点转换为实际的unicode字符串?

python - 如何为 pandas 数据框行中的每个新分组分配数值?

python - 如何将不同维度的numpy数组附加到python中已有的文本文件中

python-2.7 - 在python中使用matplotlib的3D曲面图

python - Windows错误: [Error 3] The system cannot find the path specified?

python - Unicode 字符串等价于 contains

python - 研究 Pandas DataFrame 中的不同数据类型