我有this Python script,它試圖檢測文本文件的字符編碼(在這種情況下,C#.cs
源文件,但它們可能是任何文本文件),然後轉換他們從那個字符編碼到UTF-8
(沒有BOM)。將一串文件從猜測的編碼轉換爲UTF-8
雖然chardet檢測到的編碼足夠好,並且腳本運行沒有錯誤,但©
等字符被編碼爲$
。所以我認爲腳本和我在Python 2中對編碼的理解有問題。由於將文件從UTF-8-SIG
轉換爲UTF-8
有效,我感覺問題在於解碼(讀取)部分,而不是編碼(寫入)部分。
誰能告訴我我做錯了什麼?如果切換到Python 3是一種解決方案,那麼我只需要幫助,就可以瞭解如何將腳本從2.7版轉換爲3.4版。這裏的腳本:
import os
import glob
import fnmatch
import codecs
from chardet.universaldetector import UniversalDetector
# from http://farmdev.com/talks/unicode/
def to_unicode_or_bust(obj, encoding='utf-8'):
if isinstance(obj, basestring):
if not isinstance(obj, unicode):
obj = unicode(obj, encoding)
return obj
def enforce_unicode():
detector = UniversalDetector()
for root, dirnames, filenames in os.walk('.'):
for filename in fnmatch.filter(filenames, '*.cs'):
detector.reset()
filepath = os.path.join(root, filename)
with open(filepath, 'r') as f:
for line in f:
detector.feed(line)
if detector.done: break
detector.close()
encoding = detector.result['encoding']
if encoding and not encoding == 'UTF-8':
print '%s -> UTF-8 %s' % (encoding.ljust(12), filepath)
with codecs.open(filepath, 'r', encoding=encoding) as f:
content = ''.join(f.readlines())
content = to_unicode_or_bust(content)
with codecs.open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
enforce_unicode()
我試圖寫入文件前做content = content.decode(encoding).encode('utf-8')
,但失敗,出現以下錯誤:
/usr/local/.../lib/python2.7/encodings/utf_8_sig.py:19: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
if input[:3] == codecs.BOM_UTF8:
Traceback (most recent call last):
File "./enforce-unicode.py", line 48, in <module>
enforce_unicode()
File "./enforce-unicode.py", line 43, in enforce_unicode
content = content.decode(encoding).encode('utf-8')
File "/usr/local/.../lib/python2.7/encodings/utf_8_sig.py", line 22, in decode
(output, consumed) = codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa9' in position 87: ordinal not in range(128)
想法?
我明白了。但即使在我知道原始文件位於CP1252中且正確檢測到的情況下,轉換也會失敗。 ©符號被轉換成垃圾。 – 2015-02-08 09:21:16
@asbjornu你如何顯示文件?用什麼工具打開它?你製作的其他代碼並不是在混淆任何東西。你能給我們說明問題的示例字節嗎?我放入,檢測到編解碼器以及最終寫入的字節。 – 2015-02-08 10:03:07
我最終用C#解決了這個問題,但我會接受你的答案,因爲你很可能是正確的。謝謝! – 2016-01-04 09:27:25