2013-02-20 80 views
7

在我的數據庫中,我得到的錯誤檢查UTF-8的數據類型3字節或4字節Unicode

​​

我用Java和MySQL 5,據我所知4字節Unicode是合法的Java我,但在MySQL 5非法,我認爲它可以導致我的問題,我想檢查我的數據的類型,所以這裏是我的問題: 我如何檢查我的UTF-8數據是3字節或4字節的Unicode ?

+0

我建議看你列的數據類型長度的限制和數據的大小,你想先插入。如果您將100K字符插入到「VARCHAR」中,則不會有錯誤。 – Jon 2013-02-20 13:34:07

+0

我不認爲4字節的UTF-8編碼字符是造成這個問題的原因。更可能的原因是* UTF-8編碼時需要* m *個字節(帶* m *> * n *)的* n *字符字符串,但應放入VARCHAR(* n *)中。 – 2013-02-20 13:39:38

+0

@Jon我先檢查了一下,這並不是問題,我已經解決了它,但我仍然認爲我將在未來使用編碼檢查,以幫助所有 – akuzma 2013-02-21 08:38:16

回答

15

UTF-8以1-3字節編碼基本多語言平面(即U + 0000至U + FFFF)的所有內容。因此,您只需檢查字符串中的所有內容在BMP中是否爲

在Java中,該裝置檢查任何char(其是UTF-16碼單元)是否爲高或低代理字符,如Java將使用替代對編碼非BMP字符:

public static boolean isEntirelyInBasicMultilingualPlane(String text) { 
    for (int i = 0; i < text.length(); i++) { 
     if (Character.isSurrogate(text.charAt(i))) { 
      return false; 
     } 
    } 
    return true; 
} 
10

如果你不想支持除BMP,你可以直接交給MySQL的前剝離這些字符:

public static String withNonBmpStripped(String input) { 
    if(input == null) throw new IllegalArgumentException("input"); 
    return input.replaceAll("[^\\u0000-\\uFFFF]", ""); 
} 

如果你想支持超越BMP,你需要的MySQL 5.5+,你需要改變一切的utf8utf8mb4(整理,字符集...)。但是你也需要在驅動程序中支持這個,我對此不熟悉。在Java中處理這些字符也很痛苦,因爲它們分佈在多個操作中,因此需要特殊處理。

+0

這實際上不能很好地工作,因爲正則表達式是在碼點級而不是碼單元級進行評估的。你需要匹配超出範圍\ u0000- \ uFFFF的字符(請參閱我的答案)。 – verglor 2013-11-18 04:42:16

+0

@ jako512這是令人驚訝的,因爲所有其他處理代碼單元:II已經編輯它以使用完整的非BMP字符,但原始版本背後的意圖是去除不成對的替代品 – Esailija 2013-11-18 09:32:53

+0

請注意REGEX可能會略微調整您的語言。對於PHP,使用'preg_replace('/ [^ \ x {0000} - \ x {FFFF}]/u','\ x {FFFD}',$ input);' – DOOManiac 2013-12-05 20:20:06

3

最好的辦法剝離在java中的非BMP charactres我found如下:

inputString.replaceAll("[^\\u0000-\\uFFFF]", "\uFFFD");