我有一個字符串,我從某種輸入中讀取。ruby 1.9,force_encoding,但是檢查
據我所知,它是UTF8。好的:
string.force_encoding("utf8")
但是,如果這個字符串中包含的字節實際上不是合法的UTF8,我現在想知道並採取行動。
通常情況下,force_encoding(「utf8」)會遇到這樣的字節?我認爲它不會。
如果我在做#encode,我可以從方便的選項中選擇如何處理在源編碼(或目標編碼)中無效的字符。
但我沒有做#encode,我正在做一個#force_encoding。它沒有這樣的選擇。
會是有意義的
string.force_encoding("utf8").encode("utf8")
得到一個例外,對嗎?正常編碼從 utf8 到 utf8沒有任何意義。但是,如果有無效字節,這可能是馬上讓它立即升起的方法嗎?或者使用:replace
選項等來做一些與無效字節不同的東西?
但是,不,似乎也無法做到這一點。
有人知道嗎?
1.9.3-p0 :032 > a = "bad: \xc3\x28 okay".force_encoding("utf-8")
=> "bad: \xC3(okay"
1.9.3-p0 :033 > a.valid_encoding?
=> false
好吧,但我如何找到並消除這些壞字節?奇怪的是,這不會提高:
1.9.3-p0 :035 > a.encode("utf-8")
=> "bad: \xC3(okay"
如果我轉換到不同的編碼,它會!
1.9.3-p0 :039 > a.encode("ISO-8859-1")
Encoding::InvalidByteSequenceError: "\xC3" followed by "(" on UTF-8
或者如果我告訴它,它會用「?」代替它。 =>
1.9.3-p0 :040 > a.encode("ISO-8859-1", :invalid => :replace)
=> "bad: ?(okay"
因此Ruby的得到了智慧知道什麼是壞字節UTF-8,然後用別的東西來代替他們的 - 轉換爲不同的編碼時。但我不想想要轉換爲不同的編碼,我想留在utf8 - 但我可能想提出如果有一個無效的字節在那裏,或者我可能想用替換字符替換無效的字節。
難道沒有辦法讓ruby做到這一點嗎?
更新我相信這最終被添加到2.1中的ruby中,在2.1預覽版本中使用String#scrub來執行此操作。所以找那個!
使用Ruby 1.9.3-p484,這錯誤地將ISO-8859-1文件中的\ xc0字節標記爲不正確的編碼。我發現,對於我的少數測試用例,編碼('binary',:undef =>:replace)似乎工作:iso-8859-1通過,但是序列不正確的UTF-8文件是抓住。 – 2014-02-10 19:56:06
查看[這個新答案](http://stackoverflow.com/a/21686992/238886)的代碼,不會遇到我上面提到的問題。 – 2014-02-10 20:46:22