python 中的 UTF-16 代码点计数

UTF-16 codepoint counting in python

我正在从我正在使用的 API(电报机器人)获取一些数据。 我正在使用 python-telegram-bot library which interacts with the 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' 属性中 link 的 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])

然而,上面的代码 returns: '://google.com/æøå' 显然不是实际的 url.
这样做的原因是偏移量和长度在 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 中工作也很不错。

Python已经将UTF-8编码的JSON数据正确解码为Python(Unicode)字符串,所以这里不需要处理UTF-8。

您必须编码为 UTF-16,取编码数据的长度,然后除以二。我将编码为 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)