2009-06-02 17 views
2

我需要將某些文件轉換爲UTF-8,因爲它們以UTF-8網站的形式輸出,並且內容有時看起來有點難看。將未知文件編碼批量轉換爲UTF-8

我現在可以做到這一點,或者我可以做到這一點,因爲它們被讀入(通過PHP,只是使用fopen,沒有什麼幻想)。歡迎任何建議。

+0

您確定這只是錯誤的編碼或只是一些字形缺失? – Gumbo 2009-06-02 14:13:01

+0

相當確定它是用非UTF-8字符集編寫的。多個文件顯示相同的惡意字符(e-acute等)的結果相同。 – Oli 2009-06-02 15:23:42

回答

7

我不有一個清晰的PHP解決方案,但對於Python,我個人使用了Universal Encoding Detector library,它在猜測文件編碼的編碼方面做得非常好。

爲了讓你開始,這是一個我曾經用來做轉換的Python腳本(最初的目的是我想從UTF-16和Shift-JIS的混合轉換日本代碼庫,我如果chardet對檢測編碼沒有把握,則作出默認猜測):

import sys 
import codecs 
import chardet 
from chardet.universaldetector import UniversalDetector 

""" Detects encoding 

Returns chardet result""" 
def DetectEncoding(fileHdl): 
detector = UniversalDetector() 
for line in fileHdl: 
    detector.feed(line) 
    if detector.done: break 
detector.close() 
return detector.result 


""" Reencode file to UTF-8 
""" 
def ReencodeFileToUtf8(fileName, encoding): 
    #TODO: This is dangerous ^^||, would need a backup option :) 
    #NOTE: Use 'replace' option which tolerates errorneous characters 
    data = codecs.open(fileName, 'rb', encoding, 'replace').read() 
    open(fileName, 'wb').write(data.encode('utf-8', 'replace')) 

""" Main function 
""" 
if __name__=='__main__': 
    # Check for arguments first 
    if len(sys.argv) <> 2: 
    sys.exit("Invalid arguments supplied") 

    fileName = sys.argv[1] 
    try: 
     # Open file and detect encoding 
     fileHdl = open(fileName, 'rb') 
     encResult = DetectEncoding(fileHdl) 
     fileHdl.close() 

     # Was it an empty file? 
     if encResult['confidence'] == 0 and encResult['encoding'] == None: 
      sys.exit("Possible empty file") 

     # Only attempt to reencode file if we are confident about the 
     # encoding and if it's not UTF-8 
     encoding = encResult['encoding'].lower() 
     if encResult['confidence'] >= 0.7: 
      if encoding != 'utf-8': 
       ReencodeFileToUtf8(fileName, encoding) 
     else: 
      # TODO: Probably you could make a default guess and try to encode, or 
      #  just simply make it fail 

     except IOError: 
      sys.exit('An IOError occured') 
3

這樣做只會改善性能並降低未來錯誤的可能性,但如果您不知道編碼,則根本無法進行正確的轉換。

2

我在這第一次嘗試是:

  1. 如果它在語法上是有效的UTF-8,假設它是UTF-8。
  2. 如果在ISO 8859-1(Latin-1)中只有對應於有效字符的字節,則 會假設。
  3. 否則,失敗。
1

文件是否可以包含來自不同代碼頁的數據?

如果是,那麼您根本無法進行批量轉換。你將不得不知道文件中每一個子字符串的每一個代碼頁。

如果否,可以一次批量轉換文件,但假設您知道該文件具有哪個代碼頁。所以我們或多或少地回到了上述相同的情況,我們剛剛將抽象從子字符串範圍移到了文件範圍。

所以,你需要問自己的問題是。你有關於某些數據屬於哪個代碼頁的信息嗎?如果不是,它仍然看起來很難受。

你總是可以做一些分析數據和猜測代碼頁,雖然這可能會使它有點不太fuglier,你還在猜測,因此它仍然會是fugly :)