2015-09-27 32 views
1

我得到一个错误的格式输出,当我有像“ä”,“ü”“ö”等字符。 我从excel表栏读取名称,有时会有Unicode字符串,我编码为UTF-8。我的简化代码:格式:UTF-8编码时错误的字符串宽度

import xlrd 

name1 = (xl_sheet.cell_value(row,5)).encode('utf8') # use this because this cell can have strings with chars like "ö" 
name2 = (xl_sheet.cell_value(row,7)).encode('utf8') 

print('{:<15} {:<15}'.format(name1,name2)), 

当我不使用.encode,我得到这个错误:

'ascii' codec can't encode character u'\xf6' in position 1: ordinal not in range(128) 

我发现了一个类似的帖子:Python String format width wrong when characters like é or ö in the string,但我不知道如何实现在我的情况下!?

我的产出表是这样的:

oabcd   oabcd 
öabcd   oabcd 
oabcd   oabcd 

当F.E. char'ö'在变量中,则输出不正确。

该Excel文件具有CP-1252“Windows Unicode”编码。

xlrd.open_workbook(filename).encoding的输出是:utf_16_le。

回答

0

您链接的帖子实际上建议不要编码任何内容,并将所有内容保存为unicode。对于你的榜样,它看起来更像是:

name1=u'öabcd' 
name2='oabcd' 
print(u'{:<15} {:<15}'.format(name1,name2)), 

既然你不节约使用的变量以后反正,不用担心编码和解码的字符串。你只会混淆你自己:)

+0

这只是一个简单的例子。我在程序的早些时候有一个变量。当我尝试你的建议时,我得到了错误:UnicodeDecodeError:'ascii'编解码器无法解码位置1中的字节0xc3:序号不在范围(128)中。因此我使用了.encode()。 – user3265764

+0

那么你以后为用户保存变量......实质上,你链接的帖子建议在unicode中做所有事情,并且不要打扰ascii和编码的东西。这应该解决你在'print'语句中遇到的空间问题。你认为你可以用违规代码更新你的问题吗? – Zizouz212

1

(我假设你只打印拉丁脚本,如果你混合脚本,这将变得非常复杂,你应该可能问一个问题特别搜索答案关于这个)

这样做的一个可能的问题是结合标记。重音字母如可以保存为两个Unicode字符,o¨。这些是2个字符,但打印时只占用一个空格。对于许多组合,还有一个组合形式ö,它在一个字符中编码该字母。所以:

>>> len("ö") 
2 
>>> len("ö") 
1 

你可以尝试使用unicodedata.normalize('NFC', name)那些对转换为合并的形式,但它不会在所有情况下工作,因为不是所有的组合具有组合形式。

作为zizouz和您链接的问题指出,不要编码这些字符串之前打印它们。 printstring.format都使用unicode字符串。

2

这是很简单的:

import sys 
reload(sys) 
sys.setdefaultencoding("utf-8") 

做的伎俩。主代码中的.encode('utf8')不是必需的。

+0

哦。尼斯。如果你马上导入它,你不需要'reload(sys)'部分。 :) – Zizouz212