2015-11-11 84 views
1

我在OSX機器上運行Python 2.7。我正在嘗試在smb上分享os.walk。Python os.walk()變音符u' u0308'

for root, dirnames, filenames in os.walk("./test"): 
     for filename in filenames: 

      print filename 

      matchObj = re.match(r".*ö.*",filename,re.UNICODE) 

如果我使用它的工作原理,只要文件名不包含變音符號上面的代碼。 在我的殼的變音打印正常,但當我將它們複製回格式化Textdeditor一個UTF8(在我的情況崇高),我得到:

screenshot 預計:

filename.jpeg 
filename_ö.jpg 

當然的正則表達式失敗接着就,隨即。 如果我硬編碼的文件名,如:

re.match(r".*ö.*",'filename_ö',re.UNICODE) 

它工作正常。

我想:

os.walk(u"./test") 
filename.decode('utf8') 

但給我:

return codecs.utf_8_decode(input, errors, True) 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u0308' in position 10: ordinal not in range(128) 

u'\u0308'是變音符號上方的點。

我在看我愚蠢的東西嗎?

+0

在Python 2.x中,你需要一個Unicode對象傳遞給'os.walk()'否則你會(得到一個編碼字符串,使用Unix的原始文件名或8位字符集在Windows在Mac OS X中,文件名始終是UTF-8編碼) –

回答

5

Unicode字符可以用各種形式表示;有「ö」,但是也可以使用「o」和單獨的組合符號來表示同一個字符。 OS X通常更喜歡分離的變體,並且你的編輯器似乎不能很好地處理,這兩個單獨的字符也不會匹配你的正則表達式。

您需要規範化您的Unicode數據,如果您需要某種方式或其他特別的。請參閱unicodedata.normalize。你想要NFC標準化表格。

+0

謝謝,我會潛入它 – Tim

+0

正常工作,THX爲您快速的答案 – Tim

+1

Unicode的正常化[未在代碼中唯一的問題(http://stackoverflow.com/a/33678596/ 4279)。 – jfs

3

有幾個問題:

  1. screenshot@deceze explained是由於Unicode的正常化。注意:它不是必需的碼點看起來不同例如,O(U + 00f6)和O(U + 006F U + 0308)看起來是一樣的,我的瀏覽器

  2. r".*ö.*"在Python 2字節字符串並且該值取決於Python源文件頂部的編碼聲明(例如:# -*- coding: utf-8 -*-),例如,如果聲明的編碼是utf-8,則'ö' bytestring是兩個字節的序列'\xc3\xb6'

    正則表達式引擎無法知道應該用於解釋輸入字節串的實際編碼。

    您不應該使用bytestrings來表示文本; 使用Unicode,而不是(或者使用u''文字或在頂部加入from __future__ import unicode_literals

  3. filename.decode('utf8')引發UnicodeEncodeError如果使用os.walk(u"./test")因爲filename是Unicode了。 Python 2試圖使用默認編碼'ascii'隱式編碼filename不要解碼的Unicode:滴.decode('utf-8')

順便說一句,最後兩個問題在Python 3是不可能的:r".*ö.*"是Unicode文本,你不能創建文字非ASCII字符的字節串有,並且沒有.decode()方法(如果嘗試解碼Unicode,則會得到AttributeError)。您可以在Python 3上運行您的腳本,以檢測與Unicode相關的錯誤。

+0

OP沒有將Unicode傳遞給'os.walk()',儘管它們應該是。您可能想要更新第3點以推薦通過Unicode並刪除'.decode()' –

+0

@AlastairMcCormack:閱讀該問題。 OP已經嘗試了幾種變體。其中之一是'os.walk(u「./ test')',即使用Unicode。 – jfs

+0

Doh!對不起,老兄 –