有similiar question,但解决方案似乎不起作用。
说我编码了一个字符串:
>>> a = 'dada大大'.encode('utf-8')
>>> type(a)
<class 'bytes'>
>>> a
>>> b'dada\xe5\xa4\xa7\xe5\xa4\xa7'
我想要的是这样的:
dada\xe5\xa4\xa7\xe5\xa4\xa7
str(a)
不起作用:
>>> str(a)
>>> "b'dada\\xe5\\xa4\\xa7\\xe5\\xa4\\xa7'"
我已经尝试将stdout重定向到变量,但我仍然得到了"b'dada\\xe5\\xa4\\xa7\\xe5\\xa4\\xa7'"
。
我可以使用正则表达式处理它并得到我想要的东西,但我正在寻找一种更加pythonic的方式来做到这一点。有什么建议吗?
答案 0 :(得分:5)
由于您很高兴在评论中提及您的实际问题,我会再次更新我的答案以实际回应。原始答案可以在下面看到。
这是我发给Github Markdown API的字符串。这是可以接受unicode字符的唯一方法。我得到了带有原始字符
的渲染htmldada大大
GitHub Markdown API要求您以JSON格式发送数据。 JSON本身借用了从JavaScript转义的字符串,对于这个字符,它将是\u5927
。但是,当使用json
module时,您根本不需要担心:
from urllib import urlopen
import json
text = 'dada大大'
data = json.dumps({ mode: 'markdown', 'text': text }).encode()
r = urlopen('https://api.github.com/markdown', data)
print(r.read().decode()) # <p>dada大大</p>
正如您所看到的,API可以毫无问题地接受编码文本并正确生成正确的输出,而无需担心编码。
或者将原始API与requests
库一起使用时:
h = { 'Content-Type': 'text/plain' }
r = requests.post('https://api.github.com/markdown/raw', text.encode(), headers=h)
print(r.content.decode()) # <p>dada大大</p>
>>> a = 'dada大大'.encode('utf-8')
>>> a
b'dada\xe5\xa4\xa7\xe5\xa4\xa7'
>>> str(a)
"b'dada\\xe5\\xa4\\xa7\\xe5\\xa4\\xa7'"
>>> str(a)[2:-1]
'dada\\xe5\\xa4\\xa7\\xe5\\xa4\\xa7'
>>> print(_)
dada\xe5\xa4\xa7\xe5\xa4\xa7
当您执行str(a)
时,您将获得字节字符串的字符串表示形式。当然,当您在解释器中使用它时,解释器实际上会在其上调用repr
来显示它。包含反斜杠的字符串会将它们转义为\\
。这就是那些人来自的地方。
最后,您必须删除b'
和尾随'
以获取字节字符串的字符串表示形式的内容。
旁注:str()
和repr()
在字节对象上使用时会产生相同的结果。
根据Poke的回答,我需要的是阻止
repr
的自动转义。
不,你没有。最终字符串中没有双反斜杠。它们只出现,因为当您在REPL中输入内容时,它会在调用repr
之后将返回值输出到控制台。但这并不意味着,实际的字符串突然改变了:
>>> s = str(a)[2:-1]
>>> len(s)
28
>>> list(s)
['d', 'a', 'd', 'a', '\\', 'x', 'e', '5', '\\', 'x', 'a', '4', '\\', 'x', 'a', '7', '\\', 'x', 'e', '5', '\\', 'x', 'a', '4', '\\', 'x', 'a', '7']
如您所见,字符串中没有双反斜杠。是的,你可以再次看到它们,但这只是因为REPL打印了list(s)
的返回值。列表中的每个项目都是单个字符,包括反斜杠。它们只是再次转义,因为'\'
不是有效的字符串。
>>> '\'
SyntaxError: EOL while scanning string literal
>>> '\\'
'\\'
>>> len('\\')
1
答案 1 :(得分:4)
bytes
实际上是一个整数数组:
>>> a = 'dada大大'.encode() # 'utf-8' by default
>>> list(a)
[100, 97, 100, 97, 229, 164, 167, 229, 164, 167]
您可以使用
获取每个的十六进制值>>> list(map(hex, a))
['0x64', '0x61', '0x64', '0x61', '0xe5', '0xa4', '0xa7', '0xe5', '0xa4', '0xa7']
因此
>>> list(chr(x) if x < 128 else hex(x) for x in a)
['d', 'a', 'd', 'a', '0xe5', '0xa4', '0xa7', '0xe5', '0xa4', '0xa7']
>>> print("".join(chr(x) if x < 128 else hex(x).replace("0", "\\") for x in a))
dada\xe5\xa4\xa7\xe5\xa4\xa7
答案 2 :(得分:0)
好的,最后我找到了解决方案,它来自Python Replace \\ with \
a = 'dada大大'.encode('utf-8')
b = str(a)[2:-1].encode('utf-8').decode('unicode_escape')
也许我应该解释一下我想要的更清楚。
>>> import requests
>>> text = 'dada大大'
>>> h = {'Content-Type': 'text/plain'}
>>> r = requests.post('https://api.github.com/markdown/raw', text.encode(), headers=h)
>>> print(r.content.decode())
{"message":"Invalid request media type (expecting 'text/plain')","documentation_url":"http://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode"}
>>> print(r.content.decode('utf-8'))
{"message":"Invalid request media type (expecting 'text/plain')","documentation_url":"http://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode"}
>>> r = requests.post('https://api.github.com/markdown/raw', text.encode('utf-8'), headers=h)
>>> print(r.content.decode('utf-8'))
{"message":"Invalid request media type (expecting 'text/plain')","documentation_url":"http://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode"}