2011-05-09 58 views
3

我正在從YouTube獲取一些RSS提要,其中包含無效的UTF8。我可以創建一個類似的紅寶石串使用爲什麼不在Ruby中檢測到無效編碼?

bad_utf8 = "\u{61B36}" 
bad_utf8.encoding # => #<Encoding:UTF-8> 
bad_utf8.valid_encoding? # => true 

Ruby認爲這是一個有效的UTF-8編碼,我敢肯定它不是。

說話時,Mysql的,我得到像這樣

require 'mysql2' 
client = Mysql2::Client.new(:host => "localhost", :username => "root") 
client.query("use test"); 

bad_utf8 = "\u{61B36}" 
client.query("INSERT INTO utf8 VALUES ('#{moo}')") 

# Incorrect string value: '\xF1\xA1\xAC\xB6' for column 'string' at row 1 (Mysql2::Error) 

如何檢測或修復了這些無效的類型編碼之前,我送了他們對MySQL的錯誤?

+0

所以我覺得這個問題可能是MySQL只支持基本多文種平面,其中紅寶石支持一切。 – johnf 2011-05-09 03:10:49

+0

Ruby支持一切?從何時起? – RyanScottLewis 2011-05-09 05:49:28

回答

1

可能是因爲代碼點不在basic multilingual plane 這是MySQL允許在其「utf8」字符集中唯一的字符。

較新版本的mysql有另一個名爲「utf8mb4」的字符集,其中supports unicode characters outside the BMP

但是你可能不想使用它。仔細考慮你的用例。很少真正的人類語言(如果有的話)使用BMP以外的字符。

2

我不依賴於Ruby的內置String.valid_encoding?因爲下面也是可能的:

irb 
1.9.3-p125 :001 > bad_utf8 = "\u{0}" 
=> "\u0000" 
1.9.3-p125 :002 > bad_utf8.valid_encoding? 
=> true 
1.9.3-p125 :003 > bad_utf8.encoding 
=> #<Encoding:UTF-8> 

這是有效的UTF-8(參考:https://en.wikipedia.org/wiki/Utf8),但我發現存在字符串中的NULL字符通常是對先前轉換錯誤的暗示(例如,當從HTML頁面中發現的無效編碼信息進行代碼轉換時)。

我爲「Modified UTF-8」創建了自己的驗證函數,它可以使用:bmp_only選項來限制驗證基本多語言平面(0x1-0xffff)。對於大多數現代語言來說,這應該足夠了(參考:https://en.wikipedia.org/wiki/Unicode_plane)。

這裏找到驗證:https://gist.github.com/2295531

+0

\ u0000有效。它是排除在Java DataInput/DataOutput使用的「Modified UTF-8」的上下文中的。http://docs.oracle.com/javase/6/docs/api/java/io/DataInput.html – nessence 2012-08-16 20:34:14

+0

這是正確的。上面的要點使用了修改後的UTF-8,我會在那裏做一個說明,使其更清晰。 – lumpidu 2012-09-10 19:56:15

相關問題