我的字典看起来像这样:
{ u'Samstag & Sonntag': u'Ganztags ge\xf6ffnet', u'Freitag': u'18:00 & 22:00'}
现在我正在尝试将\xf6
替换为ö
,
但尝试.replace('\xf6', 'ö')
会返回错误:
UnicodeDecodeError:'ascii'编解码器无法将字节0xf6解码到位 0:序数不在范围内(128)
我该如何解决这个问题?
答案 0 :(得分:0)
现在编码是一个雷区,我可能会关注这个 - 如果是这样的话,请纠正我。
多年来我收集的是Python2假设ASCII,除非你在脚本的顶部定义了一个编码。主要是因为它是以这种方式编译的,或者OS /终端使用ASCII作为它的主要编码。
话虽如此,您在示例数据中看到的内容:
{ u'Samstag & Sonntag': u'Ganztags ge\xf6ffnet', u'Freitag': u'18:00 & 22:00'}
是unicode字符串的ASCII表示。有些Python需要告诉你那里有一个ö
- 但它不能用ASCII,因为ö
在ASCII table中没有任何表示。
但是当你尝试使用:
替换它时x.replace('\xf6', 'ö')
您正在尝试查找名为\xf6
的ASCII字符/字符串,该字符/字符串超出了ASCII的可接受字节范围,因此会引发异常。并且您正在尝试将其替换为另一个无效的ASCII字符,这将导致相同的异常。
因此,为什么你得到“'ascii'编解码器无法解码字节...'消息。
您可以像这样执行unicode替换:
a = u'Ganztags ge\xf6ffnet'
a.replace(u'\xf6', u'ö')
这将告诉Python找到一个unicode字符串,并用另一个unicode字符串替换它
但是输出数据在上面的示例中会产生相同的结果,因为\xf6
在unicode中是ö
。
您想要做的是将您的字符串编码为您想要使用的内容,例如 - UTF-8:
a.encode('UTF-8')
'Ganztags ge\xc3\xb6ffnet'
将UTF-8定义为您的主要编码,方法是将其放在代码的顶部:
#!/usr/bin/python
# -*- coding: UTF-8
理论上,这应该使您的应用程序更容易使用 从那时起,您可以使用UTF-8作为基础模型。
但我不知道将表示转换为ASCII ö
,因为实际上并没有这样的东西。只有不同的方式,Python会为你做这个编码魔术,让你相信它可以“只写ö”。
在Python3 中,您遇到的大多数字符串都是bytes
数据,或者与Python2略有不同。在大多数情况下,它更容易。
numerous ways to change the encoding不是标准实践的一部分。但是有办法做到这一点 最接近“好”的实践,将是locale:
locale.setlocale(locale.LC_ALL, 'sv_SE.UTF-8')
这几年我也有一个可怕的解决方案和方法,它看起来像这样(当时对我来说这是一个很棒的小屋):
您的代码通常假定/使用ASCII作为编码器/解码器
ö
不是ASCII的一部分,如果你有一些如何获得unicode字符,你总会看到\xf6
。通常情况下,如果您打印u'Ganztags ge\xf6ffnet'
,由于自动编码,它将显示为Ö,如果您需要验证输入是否与该字符串匹配,则必须比较它们u'ö' == u'ö'
,如果其他系统依赖于此数据,用他们理解的东西.encode('UTF-8')
编码。但是将\xf6
替换为ö
是一回事,只是ö
在ASCII中不存在而您需要执行u'ö'
- 这将导致相同的数据最后。
答案 1 :(得分:0)
当您使用德语时,您应该注意非ascii字符。 您知道您的系统是否更喜欢Latin1(Windows控制台和某些Unix),UTF8(大多数Linux版本)或本机unicode(Windows GUI)。
如果您可以处理所有内容,因为本机unicode事物更清晰,您应该接受u'ö'
和u'\xf6'
是相同字符的事实 - 后者只是独立于python源文件字符集。
如果你必须输出将它们存储在文件中的字节字符串,你应该用UTF8 编码它们(可以处理任何unicode字符但127以上代码的字符使用超过1个字节)或Latin1(每个字符一个字节,但仅支持低于256的unicode代码点
在这种情况下,只需使用显式编码将unicode字符串转换为字节字符串:
print u'Ganztags ge\xf6ffnet'.encode('Latin1') # or .encode('utf8')
应该给出你期望的东西。