2012-02-03 57 views
4

我從網絡獲取源代碼,有時材料的編碼不是100%UTF8字節序列有效。我使用iconv默默地忽略這些序列來獲得一個清理過的字符串。如何將不推薦使用的iconv更改爲字符串#對無效的UTF8更正進行編碼

@iconv = Iconv.new('UTF-8//IGNORE', 'UTF-8') 
valid_string = @iconv.iconv(untrusted_string) 

但是現在iconv已被棄用,我看到它的棄用警告很多。

的iconv將在未來被廢棄,用String#編碼

我試圖轉換它,使用String#encode:invalid:replace選項,但似乎並不奏效(即不正確的字節序列尚未被刪除)。什麼是使用String#編碼的正確方法?

+0

我認爲你正在嘗試的是非常危險的。文本編碼就像懷孕一樣:要麼有UTF8,要麼沒有。你不能只有一點UTF8。如果有錯誤,你*有*放棄。否則,您的轉換器可能容易受到惡意準備字符串的攻擊。 – 2012-02-03 10:06:17

+0

我正在寫一個履帶式,那裏有一個網頁,有點無效。因此清理字節是我所能做的。 – lulalala 2012-02-03 10:40:25

回答

6

問題兩個最好的方法來做到這一點,但Martijn做了一個可以理解的b當在這裏複製第二種方法到他的答案時,不正確的改變。做.encode('UTF-8',<選項>).encode('UTF-8')不起作用。正如在另一個問題的原始答案中所指出的那樣,關鍵在於編碼爲不同的編碼,然後返回到UTF-8。如果您的原始字符串已經在ruby的內部標記爲UTF-8,那麼ruby將忽略任何調用將其編碼爲UTF-8。

在以下示例中,我將使用「a#{0xFF.chr} b」.force_encoding('UTF-8')生成一個字符串,該字符串認爲是UTF-8但包含無效的UTF-8字節。

1.9.3p194 :019 > "a#{0xFF.chr}b".force_encoding('UTF-8') 
=> "a\xFFb" 
1.9.3p194 :020 > "#{0xFF.chr}".force_encoding('UTF-8').encoding 
=> #<Encoding:UTF-8> 

注編碼成UTF-8怎麼什麼都不做:

1.9.3p194 :016 > "a#{0xFF.chr}b".force_encoding('UTF-8').encode('UTF-8', :invalid => :replace, :replace => '').encode('UTF-8') 
=> "a\xFFb" 

但編碼到別的東西(UTF-16),然後返回到UTF-8清理字符串:

1.9.3p194 :017 > "a#{0xFF.chr}b".force_encoding('UTF-8').encode('UTF-16', :invalid => :replace, :replace => '').encode('UTF-8') 
=> "ab" 
+0

其實你是對的。如果我始終使用UTF-8,則在字符串上使用gsub仍會引發「無效編碼」錯誤。但是你的答案解決了這個問題。我早一定做了一個糟糕的測試。 – lulalala 2012-09-26 01:35:26

7

這已經回答了這個問題:

Is there a way in ruby 1.9 to remove invalid byte sequences from strings?

使用的Martijn鏈接到了表裏如一是要麼

untrusted_string.chars.select{|i| i.valid_encoding?}.join 

untrusted_string.encode('UTF-8', :invalid => :replace, :replace => '').encode('UTF-8') 
+0

答案表示更改編碼或編碼不會執行任何操作。所以在編寫wtf.encode('UTF-8',blah blah).encode('UTF-8')'時,首先編碼在這裏沒有效果。 – nurettin 2013-01-03 07:32:32

相關問題