2013-04-04 38 views
8

Đây là những gì tôi đang làm:của Ruby CSV UTF8 lỗi mã hóa trong khi đọc

csv = CSV.open(file_name, "r") 

Tôi sử dụng này để thử nghiệm:

line = csv.shift 
while not line.nil? 
    puts line 
    line = csv.shift 
end 

Và tôi chạy vào này:

ArgumentError: invalid byte sequence in UTF-8 

Tôi đọc số answer here và đây là những gì tôi đã thử

csv = CSV.open(file_name, "r", encoding: "windows-1251:utf-8") 

Tôi chạy vào báo lỗi sau:

Encoding::UndefinedConversionError: "\x98" to UTF-8 in conversion from Windows-1251 to UTF-8 

Sau đó, tôi tình cờ gặp một viên ngọc Ruby - charlock_holmes. Tôi figured tôi muốn thử sử dụng nó để tìm mã hóa nguồn.

CharlockHolmes::EncodingDetector.detect(File.read(file_name)) 
=> {:type=>:text, :encoding=>"windows-1252", :confidence=>37, :language=>"fr"} 

Vì vậy, tôi đã làm điều này:

csv = CSV.open(file_name, "r", encoding: "windows-1252:utf-8") 

Và vẫn nhận điều này:

Encoding::UndefinedConversionError: "\x8F" to UTF-8 in conversion from Windows-1252 to UTF-8 
+0

Dường như [this] [1] có thể hoạt động. ---- [1]: http://stackoverflow.com/a/9361667/724516 – Vighnesh

+0

Bạn có thể tải lên tệp csv của mình không? –

Trả lời

4

Dường như bạn có vấn đề với việc phát hiện mã hóa hợp lệ của tập tin của bạn. CharlockHolmes cung cấp cho bạn mẹo hữu ích của :confidence=>37 chỉ đơn giản nghĩa là mã hóa được phát hiện có thể không phải là mã đúng.

Căn cứ vào thông báo lỗi và test_transcode.rb từ https://github.com/MacRuby/MacRuby/blob/master/test-mri/test/ruby/test_transcode.rb Tôi đã tìm thấy mã hóa đi qua cả hai thông báo lỗi của bạn. Với sự giúp đỡ của String#encode thật dễ dàng để kiểm tra:

"\x8F\x98".encode("UTF-8","cp1256") # => "ڈک" 

vấn đề của bạn trông giống như liên quan chặt chẽ đến các tập tin và không ruby.

Trong trường hợp chúng tôi không chắc chắn mà mã hóa để sử dụng và có thể đồng ý để mất một số nhân vật chúng ta có thể sử dụng :invalid:undef params cho String#encode, trong trường hợp này:

"\x8F\x98".encode("UTF-8", "CP1250",:invalid => :replace, :undef => :replace, :replace => "?") # => "Ź?" 

cách khác là sử dụng Iconv*//IGNORE tùy chọn để mã hóa mục tiêu:

Iconv.iconv("UTF-8//IGNORE","CP1250", "\x8F\x98") 

Như một gợi ý mã nguồn CharlockHolmes nên được khá đi od.

PS. String.encode được giới thiệu trong ruby ​​1.9. Với ruby ​​1.8, bạn có thể sử dụng Iconv

+0

Cảm ơn bạn đã trả lời. Tôi khá chắc chắn vấn đề có liên quan đến tập tin của tôi. Tôi vẫn cần phải có khả năng phân tích nó mặc dù. Tôi ổn với việc mất một số nhân vật. Bất kỳ ý tưởng? – Vighnesh

+0

@Vighnesh cập nhật này có ý nghĩa hơn không? – chrmod

+0

ooh tốt đẹp! điều này có vẻ thực sự hữu ích. Tôi sẽ cho nó một viên đạn. Đánh giá cao nỗ lực của bạn! – Vighnesh

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