特殊字符(包含emoji)的梳理

背景知識 

  • emoji表情符號,是20世紀90年代由NTT Docomo慄田穣崇(Shigetaka Kurit)建立的,詞義來自日語(えもじ,e-moji,moji在日語中的含義是字符)。emoji可使數字通訊作到讓人如同面對面交流,避免錯誤傳達信息。
  • 自蘋果公司發佈的iOS 5輸入法中加入了emoji後,這種表情符號開始席捲全球,目前emoji已被大多數現代計算機系統所兼容的Unicode編碼採納,廣泛應用於各類手機短信和社交網絡中。
  • 所謂Emoji就是一種在Unicode位於\u1F601-\u1F64F區段的字符。這個顯然超過了目前經常使用的UTF-8字符集的編碼範圍\u0000-\uFFFF

知識點

  • 在Java裏UTF-8,只支持雙字節即\u0000-\uFFFF,emoji(🐴) => "\uD83D\uDC34"
  • 查Symbola表,咱們的目標對象大體是從
    • 1F300-1F3FF => "\uD83C\uDF00" - "\uD83C\uDFFF"
    • 1F400-1F4FF => "\uD83D\uDC00" - "\uD83D\uDCFF"
    • 1F500-1F5FF => "\uD83D\uDD00" - "\uD83D\uDDFF"
    • 1F600-1F6FF => "\uD83D\uDE00" - "\uD83D\uDEFF"
    • 1F700-1F7FF => "\uD83D\uDF00" - "\uD83D\uDFFF"

編碼知識

Code
UTF-8
UTF-16 LE
Surrogates
1F7FF F0 9F 9F BF 3D D8 FF DF D83D DFFF

UTF-16描述

Unicode的編碼空間從U+0000到U+10FFFF,共有1,112,064個碼位(code point)可用來映射字符. Unicode的編碼空間能夠劃分爲17個平面(plane),每一個平面包含216(65,536)個碼位。17個平面的碼位可表示爲從U+xx0000到U+xxFFFF,其中xx表示十六進制值從0016到1016,共計17個平面。第一個平面稱爲基本多語言平面(Basic Multilingual Plane, BMP),或稱第零平面(Plane 0)。其餘平面稱爲輔助平面(Supplementary Planes)。基本多語言平面內,從U+D800到U+DFFF之間的碼位區段是永久保留不映射到Unicode字符。UTF-16就利用保留下來的0xD800-0xDFFF區段的碼位來對輔助平面的字符的碼位進行編碼。 java

UTF-16解碼mysql

lead \ trail DC00 DC01    …    DFFF
D800 10000 10001 103FF
D801 10400 10401 107FF
  ⋮
DBFF 10FC00 10FC01 10FFFF

示例:

例如U+10437編碼:sql

  • 0x10437減去0x10000,結果爲0x00437,二進制爲0000 0000 0100 0011 0111。
  • 分區它的上10位值和下10位值(使用二進制):0000000001 and 0000110111。
  • 添加0xD800到上值,以造成高位:0xD800 + 0x0001 = 0xD801。
  • 添加0xDC00到下值,以造成低位:0xDC00 + 0x0037 = 0xDC37。
  • 下表總結了該轉換,以及其它。顏色指示如何從碼點位被分佈在所述的UTF-16字節。由UTF-16編碼過程當中加入附加位以黑色顯示。
字符 普通二進制 UTF-16二進制 UTF-16 十六進制
字符代碼
UTF-16BE
十六進制字節
UTF-16LE
十六進制字節
$ U+0024 0000 0000 0010 0100 0000 0000 0010 0100 0024 00 24 24 00
U+20AC 0010 0000 1010 1100 0010 0000 1010 1100 20AC 20 AC AC 20
𐐷  U+10437 0001 0000 0100 0011 0111 1101 1000 0000 0001 1101 1100 0011 0111 D801 DC37 D8 01 DC 37 01 D8 37 DC
𤭢 U+24B62 0010 0100 1011 0110 0010 1101 1000 0101 0010 1101 1111 0110 0010 D852 DF62 D8 52 DF 62 52 D8 62 DF

解決方案

一 數據庫

  • jar包:mysql connector版本高於5.1.13
  • mysql:utf8mb4的最低mysql版本支持版本爲5.5.3+
    • 從utf8改至utf8mb4,須要重啓mysql
    • 因爲RD不該更改mysql配置,因此須要在業務應用處,調用set names utf8mb4,以使數據以utf8mb4編碼存儲到數據庫

二 過濾

    因爲數據庫的治本方法創建在有數據存儲的全部涉獵系統都得知足上述條件,因此並非經常知足。由此還須要一個治標的方法。數據庫

public  static  void  main(String[] args) {
     String source =  "a\uD83D\uDE36b\uD83D\uDE36\uD83D\uDE36\uD83D\uDE36\uD83C\uDE3612312\uD83C\uDE36" ;
     while  ( true ) {
         Integer pos = source.indexOf( "\uD83D" );
         if  (pos == - 1 ) {
             pos = source.indexOf( "\uD83C" );
         }
         if  (pos != - 1 ) {
             source = source.substring( 0 , pos) + source.substring(pos +  2 );
         else  {
             break ;
         }
     }
     System.out.println(source);
}

文檔

http://files.cnblogs.com/files/lanelim/Symbola.pdf
相關文章
相關標籤/搜索