【问题标题】:getting bytes from unicode string in python从python中的unicode字符串获取字节
【发布时间】:2011-05-13 11:38:24
【问题描述】:

我有一个 16 位大端 unicode 字符串,表示为 u'\u4132'

如何在 python 中将其拆分为整数 41 和 32?

【问题讨论】:

  • 整个问题需要解释。没有“n 位 bigendian unicode 字符串”之类的东西。你所拥有的是一个长度为 1 的 unicode 对象。其次,表示是十六进制的。你想用u'\uabcd' 做什么?第三,你为什么要把它分成字节?

标签: python unicode byte


【解决方案1】:

这里有多种你可能想要的不同方式。

Python 2:

>>> chars = u'\u4132'.encode('utf-16be')
>>> chars
'A2'
>>> ord(chars[0])
65
>>> '%x' % ord(chars[0])
'41'
>>> hex(ord(chars[0]))
'0x41'
>>> ['%x' % ord(c) for c in chars]
['41', '32']
>>> [hex(ord(c)) for c in chars]
['0x41', '0x32']

Python 3:

>>> chars = '\u4132'.encode('utf-16be')
>>> chars
b'A2'
>>> chars = bytes('\u4132', 'utf-16be')
>>> chars  # Just the same.
b'A2'
>>> chars[0]
65
>>> '%x' % chars[0]
'41'
>>> hex(chars[0])
'0x41'
>>> ['%x' % c for c in chars]
['41', '32']
>>> [hex(c) for c in chars]
['0x41', '0x32']

【讨论】:

  • OP 似乎想要拆分代码点的字节,而不是编码代码点的字节:'\u4132' -> 41, 32。如果是这种情况,那么您的解决方案对于需要将代理对编码为 '\N{PILE OF POO}' '\U0001f4a9': list(map(hex, '\N{PILE OF POO}'.encode('utf-16be'))) = ['0xd8', '0x3d', '0xdc', '0xa9'] 而不是:list(map(hex, ord('\N{PILE OF POO}').to_bytes(4, 'big'))) = ['0x0', '0x1', '0xf4', '0xa9'] 的代码点会中断
  • @DaniloSouzaMorães Whatever OP 想要的东西很奇怪。你可能是对的;如果它是有问题的 UTF-16LE,我最多会给你 5% 的机会,但考虑到它是 UTF-16BE,我会称它为偶数。
【解决方案2】:
  • Java:"\u4132".getBytes("UTF-16BE")
  • Python 2:u'\u4132'.encode('utf-16be')
  • Python 3:'\u4132'.encode('utf-16be')

这些方法返回一个字节数组,您可以轻松地将其转换为 int 数组。但请注意,U+FFFF 以上的代码点将使用两个代码单元进行编码(因此对于 UTF-16BE,这意味着 32 位或 4 字节)。

【讨论】:

  • 为什么在python 3的字符串前使用'u'?
  • 感谢您的注意,我在答案中修复了它。
【解决方案3】:

“那些”不是整数,它是一个十六进制数,代表code point

如果您想获得代码点的整数表示,则需要使用 ord(u'\u4132'),如果您现在想将其转换回 unicode 字符,请使用 unicode(),它将返回一个 unicode 字符串。

【讨论】:

  • 是的,我知道它们不是整数,但在操作结束时我需要将 41 和 32 作为整数,这就是我提到整数的原因。作为更正“我如何将 u”\u4132“转换为字符串或 int 4132”可能会更好:)
  • @hinoglu:如果您确实想获得 41 和 32 作为整数,那么您的应用程序可能会被破坏。如果你说 u'\U412F' 而不是 u'\U4132' ,它应该有什么明智的行为?哪个和另一个一样有效。可能有理由想要从上面获取字符串“4132”(或“412F”)我无法想象想要获取整数 4132 的任何合理理由。除了可能是将其转换回字符串“4132” ' ?你能解释一下你的用例吗?
【解决方案4】:
>>> c = u'\u4132'
>>> '%x' % ord(c)
'4132'

【讨论】:

    【解决方案5】:

    肮脏的 hack:repr(u'\u4132') 将返回 "u'\\u4132'"

    【讨论】:

    • 呃。 看看其他答案(多么巧合 - 我写了一个;-)) - 他们实现了同样的事情没有那个可怕的黑客!
    【解决方案6】:

    将 unicode 字符传递给 ord() 以获取其代码点,然后使用 int.to_bytes() 将该代码点分解为单个字节,然后根据需要格式化输出:

    list(map(lambda b: hex(b)[2:], ord('\u4132').to_bytes(4, 'big')))
    

    返回:['0', '0', '41', '32']

    list(map(lambda b: hex(b)[2:], ord('\N{PILE OF POO}').to_bytes(4, 'big')))
    

    返回:['0', '1', 'f4', 'a9']

    正如我在另一条评论中提到的,将代码点编码为 utf16 对于 BMP(基本多语言平面)之外的代码点将无法正常工作,因为 UTF16 需要一个代理对来对这些代码点进行编码。

    【讨论】:

      猜你喜欢
      • 2018-08-15
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      • 2012-04-21
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多