2013-09-02 28 views
5

Tôi biết thêm về sửa chữa xe đạp, sử dụng cưa và an toàn rãnh hơn là tôi sử dụng mã hóa Python hoặc văn bản; với ý nghĩ đó ...Những cạm bẫy trong mã của tôi để phát hiện mã hóa tệp văn bản bằng Python?

Mã hóa văn bản Python có vẻ là vấn đề lâu năm (câu hỏi của riêng tôi: Searching text files' contents with various encodings with Python? và những người khác tôi đã đọc: 1, 2. Tôi đã viết một số mã để đoán mã hóa dưới đây.

trong thử nghiệm hạn chế mã này dường như làm việc cho các mục đích của tôi * mà không có tôi cần phải biết sự dư thừa về ba byte đầu tiên của mã hóa văn bản và các tình huống mà những dữ liệu không được nhiều thông tin.

* Mục đích của tôi là:

  1. Có đoạn mã phụ thuộc miễn phí mà tôi có thể sử dụng với mức độ thành công cao,
  2. Quét máy trạm cục bộ cho tệp nhật ký dựa trên văn bản của bất kỳ mã hóa nào và xác định chúng dưới dạng tệp tôi quan tâm dựa trên nội dung của chúng (yêu cầu tệp phải được mở bằng mã hóa thích hợp)
  3. để khắc phục sự cố này.

Câu hỏi: những cạm bẫy với việc sử dụng một những gì tôi giả định là một phương pháp klutzy so sánh và đếm ký tự như tôi làm dưới đây là gì? Bất kỳ đầu vào được đánh giá rất nhiều.

def guess_encoding_debug(file_path): 
    """ 
    DEBUG - returns many 2 value tuples 
    Will return list of all possible text encodings with a count of the number of chars 
    read that are common characters, which might be a symptom of success. 
    SEE warnings in sister function 
    """ 

    import codecs 
    import string 
    from operator import itemgetter 

    READ_LEN = 1000 
    ENCODINGS = ['ascii','cp1252','mac_roman','utf_8','utf_16','utf_16_le',\ 
       'utf_16_be','utf_32','utf_32_le','utf_32_be'] 

    #chars in the regular ascii printable set are BY FAR the most common 
    #in most files written in English, so their presence suggests the file 
    #was decoded correctly. 
    nonsuspect_chars = string.printable 

    #to be a list of 2 value tuples 
    results = [] 

    for e in ENCODINGS: 
     #some encodings will cause an exception with an incompatible file, 
     #they are invalid encoding, so use try to exclude them from results[] 
     try: 
      with codecs.open(file_path, 'r', e) as f: 

       #sample from the beginning of the file 
       data = f.read(READ_LEN) 

       nonsuspect_sum = 0 

       #count the number of printable ascii chars in the 
       #READ_LEN sized sample of the file 
       for n in nonsuspect_chars: 
        nonsuspect_sum += data.count(n) 

       #if there are more chars than READ_LEN 
       #the encoding is wrong and bloating the data 
       if nonsuspect_sum <= READ_LEN: 
        results.append([e, nonsuspect_sum]) 
     except: 
      pass 

    #sort results descending based on nonsuspect_sum portion of 
    #tuple (itemgetter index 1). 
    results = sorted(results, key=itemgetter(1), reverse=True) 

    return results 


def guess_encoding(file_path): 
    """ 
    Stupid, simple, slow, brute and yet slightly accurate text file encoding guessing. 
    Will return one likely text encoding, though there may be others just as likely. 
    WARNING: DO NOT use if your file uses any significant number of characters 
      outside the standard ASCII printable characters! 
    WARNING: DO NOT use for critical applications, this code will fail you. 
    """ 

    results = guess_encoding_debug(file_path) 

    #return the encoding string (second 0 index) from the first 
    #result in descending list of encodings (first 0 index) 
    return results[0][0] 

Tôi cho rằng nó sẽ chậm so với chardet mà tôi không quen thuộc lắm. Cũng kém chính xác hơn. Cách chúng được thiết kế, bất kỳ ngôn ngữ dựa trên ký tự La Mã nào sử dụng dấu trọng âm, âm sắc, v.v. sẽ không hoạt động, ít nhất là không tốt. Sẽ rất khó để biết khi nào nó không thành công. Tuy nhiên, hầu hết các văn bản bằng tiếng Anh, bao gồm hầu hết các mã lập trình, phần lớn sẽ được viết bằng string.printable trên đó mã này phụ thuộc.

thư viện bên ngoài có thể là một lựa chọn trong tương lai, nhưng bây giờ tôi muốn tránh họ bởi vì:

  1. Kịch bản này sẽ được chạy trên nhiều máy tính công ty trong và ngoài mạng với các phiên bản khác nhau của trăn, vì vậy càng ít biến chứng càng tốt. Khi tôi nói 'công ty' tôi có nghĩa là một tổ chức phi lợi nhuận nhỏ của các nhà khoa học xã hội.
  2. Tôi phụ trách việc thu thập nhật ký từ xử lý dữ liệu GPS, nhưng tôi không phải là quản trị viên hệ thống - cô ấy không phải là lập trình viên python và thời gian tôi mất ít thời gian hơn.
  3. Việc cài đặt Python thường có sẵn tại công ty của tôi được cài đặt với gói phần mềm GIS và thường tốt hơn khi ở một mình.
  4. Yêu cầu của tôi không quá nghiêm ngặt, tôi chỉ muốn xác định các tệp mà tôi quan tâm và sử dụng các phương pháp khác để sao chép chúng vào lưu trữ. Tôi không đọc toàn bộ nội dung vào bộ nhớ để thao tác, thêm hoặc viết lại nội dung.
  5. Có vẻ như một ngôn ngữ lập trình cấp cao nên có một số cách tự hoàn thành điều này. Trong khi "có vẻ như" là một nền tảng run rẩy cho bất kỳ nỗ lực nào, tôi muốn thử và xem liệu tôi có thể làm cho nó hoạt động được không.
+0

+1 cho câu hỏi hay! cũng được nghiên cứu, ví dụ tốt bằng văn bản quá. –

+1

Bất kỳ lý do nào để không thử thư viện hiện có? Giống như chardet hoặc chared (https://code.google.com/p/chared/)? – amit

+0

Từ những gì tôi hiểu có một số thư viện rất tốt có sẵn cho loại này, chẳng hạn như những người bạn đã đề cập. Tôi hy vọng có thời gian để học cách sử dụng chúng như tôi chắc chắn rằng chúng mạnh hơn những gì tôi có thể nghĩ ra. Tuy nhiên, có nhiều lý do để tránh thư viện bên ngoài. Tôi đã chỉnh sửa bài đăng của mình để nêu rõ hơn lý do của tôi. –

Trả lời

0

Có lẽ cách đơn giản nhất để tìm hiểu xem mã của bạn hoạt động tốt như thế nào để thực hiện các bộ thử cho các thư viện hiện có khác và sử dụng chúng làm cơ sở để tạo bộ thử nghiệm toàn diện của riêng bạn.Họ sẽ biết liệu mã của bạn có hoạt động cho tất cả các trường hợp đó hay không và bạn cũng có thể kiểm tra tất cả các trường hợp mà bạn quan tâm.

Các vấn đề liên quan