繁体   English   中英

我如何解码这个utf-8字符串,在随机网站上挑选并由Django ORM使用Python保存?

[英]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

另请参见: http//www.joelonsoftware.com/articles/Unicode.html

也许我太天真,但是......是不是你的问题只是其躲过了领先\\ 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM