[英]How can I decode this utf-8 string, picked on a random website and saved by the Django ORM, using Python?
我解析了一个文件并使用Django将其内容保存在数据库中。 该网站是100%的英文,所以我天真地认为它一直是ASCII,并愉快地保存文本作为unicode。
你猜其余的故事:-)
当我打印时,我得到通常的编码错误:
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 48: ordinal not in range(128)
快速搜索告诉我,''u2019'是'的'UTF-8表示'
。
repr(string)
显示我:
"u'his son\\u2019s friend'"
然后当然我尝试了django.utils.encoding.smart_str
和一个更直接的方法使用string.encode('utf-8'),我最终得到了一些可打印的东西。 不幸的是,它在我的(linux UTF-8)终端中打印出来:
In [76]: repr(string.encode('utf-8'))
Out[76]: "'his son\\xe2\\x80\\x99s friend '"
In [77]: print string.encode('utf-8')
his son�s friend
不是我的预期。 我怀疑我对某些东西进行了双重编码或错过了一个重点。
当然文件原始编码不是与文件一起建立的。 我想我可以阅读HTTP标题或询问网站管理员,但由于\\ u2019s看起来像UTF-8,我认为它是utf-8。 我可能是非常错的,告诉我,如果我。
解决方案显然很受欢迎,但对原因的深刻解释以及如何避免再次发生这种情况将会更多。 我经常被编码所困扰,这表明我仍然没有完全掌握主题。
你很好。 你有适当的数据。 是的,原始数据是UTF-8(基于上下文u2019作为“儿子”和“s”之间的撇号非常有意义)。 奇怪的?
错误字符可能只是意味着您的终端配置的字体没有此字符的字形(花式撇号)。 没什么大不了。 数据在重要的地方是正确的。 如果您感到紧张,请尝试一些不同的终端/操作系统组合(我使用iTerm在OS X上)。 我花了很多时间向我的QA人解释这可怕?
问号字符只是意味着他们的Windows框中没有安装中文字体(在我的情况下,我们使用中文数据进行测试)。 这是一些评论
#Create a Python Unicode object
#(abstract code points, independent of any encoding)
#single backslash tells python we want to represent
#a code point by its unicode code point number, typed out with ASCII numbers
>>> s1 = u'his son\u2019s friend'
#If you just type it at the prompt,
#the interpreter does the equivalent of `print repr(s1)`
#and since repr means "show it like a string typed into a python source file",
#you get your ASCII escaped version back
>>> s1
u'his son\u2019s friend'
>>> print repr(s1)
u'his son\u2019s friend'
#This isn't ASCII, so encoding into ASCII generates your original
#error as expected
>>> s1.encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character
u'\u2019' in position 7:
ordinal not in range(128)
# Encode in UTF-8 and now we have a string,
# which gets displayed as hex escapes.
#Unicode code point 2019 looks like it gets 3 bytes in UTF-8 (yup, it does)
>>> s1.encode('utf-8')
'his son\xe2\x80\x99s friend'
#My terminal DOES have a different glyph (symbol) to use here,
#so it displays OK for me.
#Note that my terminal has a different glyph for a normal ASCII apostrophe
#(straight vertical)
>>> print s1
his son’s friend
>>> repr(s1)
"u'his son\\u2019s friend'"
>>> str(s1.encode('utf-8'))
'his son\xe2\x80\x99s friend'
另见: http : //www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
另请参阅字符2019(十六进制的e28099,在此页面上搜索“2019”): http ://www.utf8-chartable.de/unicode-utf8-table.pl?start = 8000
也许我太天真,但是......是不是你的问题只是其躲过了领先\\
Unicode代码点的?
您的原始字符串表现如下:
>>> s = u'his son\\u2019s friend'
>>> print(s)
his son\u2019s friend
但删除转义\\
给出:
>>> s = u'his son\u2019s friend'
>>> print(s)
his son’s friend
尝试调用这样的python shell:
python2 -S -i -c 'import sys;sys.setdefaultencoding("utf-8");import site'
然后:
>>> s = u'his son\u2019s friend'
>>> print s.encode("utf-8")
his son’s friend
然后默认编码是utf-8,它应该打印正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.