问一个让我很困扰的编码问题。

2018-03-01 11:14:59 +08:00
 SimbaPeng
Py3.6

>>> r'\u4e2d'.encode('unicode_escape')
b'\\\\u4e2d'
>>> b'\\\\u4e2d'.decode('unicode_escape')
'\\u4e2d'
>>> b'\u005c\u0075\u0034\u0065\u0032\u0064'.decode('unicode_escape')
'\\u4e2d'
>>> b'\u005c\u0075\u0034\u0065\u0032\u0064'.decode('unicode_escape') == b'\\\\u4e2d'.decode('unicode_escape')
True
>>> b'\u005c\u0075\u0034\u0065\u0032\u0064' == b'\\\\u4e2d'
False


r'\u4e2d' 的 unicode 编码应该是 b'\u005c\u0075\u0034\u0065\u0032\u0064'这个阿,为什么 encode('unicode_escape')出来的是 b'\\\\u4e2d'这个?

而且 b'\\\\u4e2d'和 b'\u005c\u0075\u0034\u0065\u0032\u0064' 都可以解码出来 r'\u4e2d',这是为什么?
1760 次点击
所在节点    Python
2 条回复
imn1
2018-03-01 11:46:49 +08:00
你比较一下这个
r'\u4e2d'.encode('raw_unicode_escape')

然后再看看文档,搞清楚 unicode_escape 的行为是什么
scriptB0y
2018-03-01 11:47:51 +08:00
有意思,我昨天刚纠结了这个问题。

unicode-escape 先 encode()然后按照字面 escape 一次。

In [32]: "中国".encode('unicode-escape')
Out[32]: b'\\u4e2d\\u56fd'

In [33]: "中国".encode()
Out[33]: b'\xe4\xb8\xad\xe5\x9b\xbd'

In [34]: len(b'\\u4e2d\\u56fd')
Out[34]: 12

所以你的 r'\u4e2d'.encode('unicode-escape') 实际上是这样:

In [36]: r'\u4e2b'.encode()
Out[36]: b'\\u4e2b'

先 encode()的到了 b'\\u4e2b' , 这个时候得到 6 个 byte, \ u 4 e 2 b,注意只有一个 \ ,前面一个是转义用的。

再按照字面意思就是 \ \ u 4 e 2 b 一共 7 个字符对吧。前面转义的 \ 也被按照字面解释成了一个 \ 。

第一个问题回答完毕。
-----------------------------------


解码问题:

解码的时候,unicode-escape 可能将多个 byte 解释成一个,例如

对于 b'\\\\u4e2d' escape 这一步变成 \\u4e2d,从 7 个字符变成了 6 个。

对于 b'\u005c\u0075\u0034\u0065\u0032\u0064' , 从 36 个变成了 6 个。

再啰嗦一点,前者, 第一个 \ 转义了第二个 \ 结束了。 后者第一个 \ 转义了 u 继续向后直到 \u005c 被解释成 1 个字符。

所以两者 decode('unicode-escape')的结果是一样的。

昨天的帖子: https://www.kawabangga.com/posts/2767

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/433812

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX