【问题标题】:Removing literal backslashes from utf-8 encoded strings in python从python中的utf-8编码字符串中删除文字反斜杠
【发布时间】:2022-08-23 04:41:11
【问题描述】:

我有一堆包含 UTF-8 编码符号的字符串,例如\'\\\\u00f0\\\\u009f\\\\u0098\\\\u0086\'。 在这种情况下,它表示这个表情符号 ????,以 UTF-8 编码。我希望能够将其替换为文字表情符号。有人向我推荐的解决方案是将其编码为latin-1,然后将其解码为utf-8。所以,

\'\\u00f0\\u009f\\u0098\\u0086\'.encode(\'latin-1\').decode(\'utf-8\')

给我输出

\'????\'

不幸的是,所有带有这些代码的字符串都有一个文字反斜杠,所以每当我做同样的操作时,

\'\\\\u00f0\\\\u009f\\\\u0098\\\\u0086\'.encode(\'latin-1\').decode(\'utf-8\')

我得到以下结果,

\'\\\\u00f0\\\\u009f\\\\u0098\\\\u0086\'

有没有办法删除那些反斜杠?因为如果我用空字符串替换它们,所有反斜杠都会消失。

  • 你的标题有点误导。您不仅想消除反斜杠,还想转换与它们一起出现的整个序列。

标签: python string unicode utf-8


【解决方案1】:

我不知道你从哪里得到那个字符串,但它是一种……不寻常的……表示代码点的方式。 U+1F606 张开嘴和紧闭眼睛的笑脸以 UTF-8 编码为字节F0 9F 98 86。在 Python 字符串转义中,\uXXXX 用于表示基本多语言平面中的整个代码点,\UXXXXXXXX 用于表示超出它的代码点(就像这个),而不是其 UTF-8 编码的单个字节。所以你希望看到它在字符串中表示为'\U0001F606'

无论如何,以下将提取每个转义序列的最后两个十六进制数字,将它们转换为字节数组,然后将生成的 UTF-8 数据解码为字符串:

import re
str='\\u00f0\\u009f\\u0098\\u0086'
print(b''.join([ bytes.fromhex(m.group(1)) for m in re.finditer(r'\\u[0-9a-fA-F]{2}([0-9a-fA-F]{2})', str) ]).decode())
# Displays ?

【讨论】:

  • 从你的earlier question,听起来你是从 facebook 提供的 JSON 中获取这个字符串的?代码点应该在纯 ASCII JSON 中编码为"\ud83d\ude06",并由任何 JSON 解析器进行适当转换。
  • 非常感谢,如果这个问题具有误导性,我很抱歉,意识到我需要做什么让我有点困惑。另外,我从 Facebook Messenger 下载了这些数据,它是一个 .json 文件,其中包含消息和反应(表情符号)等信息,这就是为什么我有很多这样的代码。由于某种原因,所有非 ASCII 代码都被转换为这种奇怪的代码。
  • 也许在管道的某个地方发生了一些 mojibake。
  • @Shawn我不认为这是mojibake,我认为这是JSON指定要编码的复杂Unicode字符的方式。
  • @MarkRansom 不,这不是 JSON 的工作方式。它对每个代码点使用一个或两个 \uXXXX 转义(两个是​​ BMP 之外的 UTF-16 代理对)
【解决方案2】:

b'\\u00f0\\u009f\\u0098\\u0086' 可以使用编码“unicode_escape”直接解码。

例如:

>>> b'\\u00f0\\u009f\\u0098\\u0086'.decode("unicode_escape")
'ð\x9f\x98\x86'

请注意,这将自行删除转义的反斜杠!例如,以下 JSON 将中断:

>>> encoded_json = b'{"a":"Basic realm=\\"Dost\\udceapz"}'
>>> encoded_json.decode("unicode_escape")
'{"a":"Basic realm="Dost\udceapz"}'
>>> json.loads(encoded_json)
{'a': 'Basic realm="Dost\udceapz'}
>>> json.loads(encoded_json.decode("unicode_escape"))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/javier/.pyenv/versions/3.6.15/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/home/javier/.pyenv/versions/3.6.15/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/home/javier/.pyenv/versions/3.6.15/lib/python3.6/json/decoder.py", line 355, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 1 column 20 (char 19)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-28
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多