1. 程式人生 > >微信公眾平臺暱稱亂碼emoji表情過濾

微信公眾平臺暱稱亂碼emoji表情過濾

問題描述

最近在對線上排錯過程中發現很多入庫時產生的錯誤日誌,表現形態如下

Incorrect string value : '\xF0\x9F\x91\x8D\xE6\x94...' for column 'column_x' at row 1

在查閱資料後發現這其實是一種emoji表情符號,普遍存在iOS與android系統中,而這種特殊字符合作用的Unicode 6標準來統一,採用4個bytes來儲存一個emoji表情,而將這種表情不處理直接儲存到MySQL5.5以下的版本會報錯,當然想要MySQL儲存這種字元也不困難,只需要修改資料庫字符集為utf8mb4即可,但資料回傳給網頁或者移動客戶端時則需要做相容處理,所以我們暫時忽略這種需求,直接將其過濾掉.

解決方案

對於字串處理,首選就是正則表示式去處理,而在android系統中可以自定義InputFilter去過濾需要處理掉的字串,程式碼如下

InputFilter emojiFilter = new InputFilter ( ) {

@Override

public CharSequence filter ( CharSequence source , int start , int end , Spanned dest , int dstart ,

int dend ) {

} } ;

隨後我查閱了 emoji 的wikipedia與 Github

,從中提取出表情的一個大概unicode範圍,由於Java可以直接對unicode進行匹配,這樣我們可以很省事直接寫出Pattern即可,程式碼如下

InputFilter emojiFilter = new InputFilter ( ) {

Pattern emoji = Pattern . compile (

"[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]" ,

Pattern . UNICODE_CASE | Pattern . CASE_INSENSITIVE ) ;

@Override

public CharSequence filter ( CharSequence source , int start , int end , Spanned dest , int dstart ,

int dend ) {

Matcher emojiMatcher = emoji . matcher ( source ) ;

if ( emojiMatcher . find ( ) ) {

return "" ;

}

return null ;

} } ;

基本上這樣就能過濾掉emoji表情了