UTF-16码点在python中计数

时间:2016-09-01 20:13:50

标签: python python-3.x encoding utf-8 utf-16

我从我正在使用的API(电报机器人)获取一些数据。 我正在使用与python-telegram-bot互动的Telegram Bot api库。 数据以JSON格式以UTF-8编码返回。 示例(摘录):

{'message': {'text': '\u200d\u200d\u200dhttp://google.com/æøå', 'entities': [{'type': 'url', 'length': 21, 'offset': 11}], 'message_id': 2655}}

可以看出,'entities'包含url类型的单个实体,它有一个长度和一个偏移量。 现在说我想在'text'属性中提取链接的url:

data = {'message': {'text': '\u200d\u200d\u200dhttp://google.com/æøå', 'entities': [{'type': 'url', 'length': 21, 'offset': 11}], 'message_id': 2655}}
entities = data['entities']
for entity in entities:
    start = entity['offset']
    end = start + entity['length']
    print('Url: ', text[start:end])

然而,上面的代码会返回'://google.com/æøå',这显然不是实际的网址 原因是偏移量和长度是UTF-16码点。所以我的问题是:有没有办法在python中使用UTF-16代码点?我不需要能够计算它们。

我已经尝试过了:

text.encode('utf-8').decode('utf-16')

但是这会产生错误:UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0xa5 in position 48: truncated data

非常感谢任何帮助。 我正在使用python 3.5,但是因为它是一个统一的库,所以在python 2.x中也可以使用它。

1 个答案:

答案 0 :(得分:4)

Python已经将UTF-8编码的JSON数据正确解码为Python(Unicode)字符串,因此无需在此处理UTF-8。

您必须编码为UTF-16,取编码数据的长度,然后除以2。我编码为utf-16-leutf-16-be以防止添加BOM:

>>> len(text.encode('utf-16-le')) // 2
32

要使用实体偏移,您可以编码为UTF-16,切片加倍偏移,然后再次解码:

text_utf16 = text.encode('utf-16-le')
for entity in entities:
    start = entity['offset']
    end = start + entity['length']
    entity_text = text_utf16[start * 2:end * 2].decode('utf-16-le')
    print('Url: ', entity_text)