2011-08-13 4 views
46

मैं रूबी 1.9.2रूबी सीएसवी UTF-8 के रूप में फाइल और/या UTF-8

मैं कोशिश कर रहा हूँ एक CSV फ़ाइल है कि कुछ फ्रेंच शामिल पार्स उपयोग कर रहा हूँ करने के लिए ASCII-8 बिट एन्कोडिंग परिवर्तित पढ़ शब्द (उदाहरण के लिए spécifié) और सामग्री को एक MySQL डेटाबेस में रखें।

जब मैं CSV फ़ाइल से लाइनों को पढ़ने,

file_contents = CSV.read("csvfile.csv", col_sep: "$") 

तत्वों स्ट्रिंग्स हैं ASCII-8bit इनकोडिंग (specifie एसपी \ xE9cifi \ xE9 हो जाता है), और "specifie तरह तारों के रूप में वापस आने के लिए "तब मेरे MySQL डेटाबेस में ठीक तरह से सहेजा नहीं जाता है।

Yehuda Katz कहता है कि ASCII-8BIT वास्तव में "बाइनरी" डेटा है जिसका अर्थ है कि सीएसवी को उचित एन्कोडिंग को पढ़ने का तरीका नहीं है।

तो, अगर मैं बनाने की कोशिश सीएसवी इस तरह एन्कोडिंग मजबूर:

file_contents = CSV.read("csvfile.csv", col_sep: "$", encoding: "UTF-8")

मैं निम्न त्रुटि

ArgumentError: invalid byte sequence in UTF-8: 

मिलता है मैं अपने मूल ASCII-8 बिट एन्कोड करने के लिए वापस जाने के लिए स्ट्रिंग्स और स्ट्रिंग की जांच करें कि मेरा सीएसवी ASCII-8BIT के रूप में पढ़ता है, ऐसा लगता है कि यह "गैर spécifié" के बजाय "गैर sp \ xE9cifi \ xE9" जैसा दिखता है।

मैं "गैर एसपी \ xE9cifi \ xE9" "गैर specifie" परिवर्तित नहीं कर सकते इस "Non sp\xE9cifi\xE9".encode("UTF-8")

करके क्योंकि मैं इस त्रुटि मिलती है:

Encoding::UndefinedConversionError: "\xE9" from ASCII-8BIT to UTF-8,

जो Katz संकेत दिया ऐसा होगा क्योंकि ASCII-8BIT वास्तव में एक उचित स्ट्रिंग "एन्कोडिंग" नहीं है।

सवाल:

  1. मैं सीएसवी उचित एन्कोडिंग में मेरी फाइल को पढ़ने के लिए मिल सकता है? यदि हां, तो कैसे?
  2. MySQL में उचित संग्रहण के लिए मैं ASCII-8BIT स्ट्रिंग को UTF-8 में कैसे परिवर्तित करूं?
+0

ऐसा लगता है कि फ़ाइल को UTF-8 नहीं हो सकता है इनकोडिंग; क्या आपने फ़ाइल के वास्तविक एन्कोडिंग की जांच की है? – coreyward

+3

आपकी फ़ाइल यूटीएफ -8 में एन्कोड नहीं है। यूटीएफ -8 में 'सी 3 ए 9 'होना चाहिए, न कि' E9'। ऐसा लगता है कि आप इसके बजाय आईएसओ -885 9 -1 से निपट रहे हैं। – deceze

+3

मुझे लगता है मैं यह पता लगा: my_ascii_8bit_string.unpack ("सी *") पैक ("यू *") काम करने के लिए लगता है।। – user141146

उत्तर

51

deceze कि iso8859-1 (उर्फ लैटिन -1) इनकोडिंग पाठ है सही है,। इस प्रयास करें:

file_contents = CSV.read("csvfile.csv", col_sep: "$", encoding: "ISO8859-1") 

और यदि काम नहीं करता है, तो आप Iconv का उपयोग कुछ इस तरह के साथ व्यक्तिगत तार ऊपर ठीक करने के लिए कर सकते हैं:

require 'iconv' 
utf8_string = Iconv.iconv('utf-8', 'iso8859-1', latin1_string).first 

तो latin1_string"Non sp\xE9cifi\xE9" है, तो utf8_string"Non spécifié" हो जाएगा ।इसके अलावा, Iconv.iconv एक समय में पूरे सरणियों unmangle कर सकते हैं:

utf8_strings = Iconv.iconv('utf-8', 'iso8859-1', *latin1_strings) 
नए माणिक के साथ

, तो आप इस तरह कर सकते हैं:

utf8_string = latin1_string.force_encoding('iso-8859-1').encode('utf-8') 

जहां latin1_string सोचता है कि यह ASCII-8 बिट में है, लेकिन आईएसओ में वास्तव में है -8,859-1।

+1

बहुत बहुत धन्यवाद। – user141146

+2

ध्यान दें कि रूबी अब आप 'उपयोग करने के लिए नहीं बल्कि' iconv' का उपयोग करने से स्ट्रिंग # encode' चाहता है। – duma

+1

@ ड्यूमा: अब बेहतर है? मैंने पुरानी Iconv सामग्री छोड़ी और Iconv के बजाय 'force_encoding' और' encode' का उपयोग करने के बारे में एक संक्षिप्त नोट जोड़ा। –

1

मैं थोड़ी देर और अन्य समाधान के किसी भी नहीं करने के लिए इस मुद्दे के साथ काम कर दिया है मेरे लिए काम किया।

बात यह है कि चाल बना एक द्विआधारी फ़ाइल में conflictive स्ट्रिंग स्टोर करने के लिए, फिर फ़ाइल सामान्य रूप से पढ़ सकते हैं और सीएसवी मॉड्यूल को खिलाने के लिए इस स्ट्रिंग का उपयोग कर रहा था:

tempfile = Tempfile.new("conflictive_string") 
tempfile.binmode 
tempfile.write(conflictive_string) 
tempfile.close 
cleaned_string = File.read(tempfile.path) 
File.delete(tempfile.path) 
csv = CSV.new(cleaned_string) 
21

के साथ गहरे लाल रंग का> = 1.9 आप

file_contents = CSV.read("csvfile.csv", col_sep: "$", encoding: "ISO8859-1:utf-8") 

ISO8859-1:utf-8 अर्थ है उपयोग कर सकते हैं: सीएसवी फ़ाइल iso8859-1 है - एन्कोडेड है, लेकिन conve utf-8 के लिए सामग्री

आप एक अधिक वर्बोज़ कोड चाहें, तो आप उपयोग कर सकते हैं आर टी:

file_contents = CSV.read("csvfile.csv", col_sep: "$", 
    external_encoding: "ISO8859-1", 
    internal_encoding: "utf-8" 
) 
+0

इस जवाब बेहतर तो स्वीकार किए जाते हैं एक – serggl

+0

यह अद्भुत है लग रहा है । से पहले, मैं इस UTF-16 सीएसवी के लिए एक 'bom' में डालने के लिए किया था:' '' CSV.read ('nom_nom_nom.csv', {: हेडर => true,: col_sep => "\ t",: एन्कोडिंग = > 'बॉम | utf-16le'}) '' ', अन्यथा यह त्रुटियों को फेंक देगा। अब यह है: '' 'CSV.read ('nom_nom_nom.csv', {: headers => true,: col_sep =>" \ t ", बाहरी_एन्कोडिंग: 'utf-16', internal_encoding:" utf- 8 "}) ' ''। – Hahn

संबंधित मुद्दे