2015-09-27 63 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