『壹』 檢測文本中是否有emoji字元以及過濾
<span style="font-family: Arial, Helvetica, sans-serif;">過濾該表情</span>
[java] view plain
public static String filterEmoji(String source) {
if (!containsEmoji(source)) {
return source;// 如果不包含,直接返回
}
StringBuilder buf = null;
int len = source.length();
for (int i = 0; i < len; i++) {
char codePoint = source.charAt(i);
if (!isEmojiCharacter(codePoint)) {
if (buf == null) {
buf = new StringBuilder(source.length());
}
buf.append(codePoint);
} else {
}
}
if (buf == null) {
return "";
} else {
if (buf.length() == len) {// 這里的意義在於盡可能少的toString,因為會重新生成字元串
buf = null;
return source;
} else {
return buf.toString();
}
}
}
[java] view plain
// 判別是否包含Emoji表情
private static boolean containsEmoji(String str) {
int len = str.length();
for (int i = 0; i < len; i++) {
if (isEmojiCharacter(str.charAt(i))) {
return true;
}
}
return false;
}
private static boolean isEmojiCharacter(char codePoint) {
return !((codePoint == 0x0) ||
(codePoint == 0x9) ||
(codePoint == 0xA) ||
(codePoint == 0xD) ||
((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
((codePoint >= 0x10000) && (codePoint <= 0x10FFFF)));
}
『貳』 python 怎麼過濾 emoji 表情符號
用
string =「你猜猜em[4500]48570em[2250]」
cc = re.findall('[\u4e00-\u9fa5]', string)
cc="你猜猜"
去提取中文或者英文不也可以達到去除表情符號的作用嗎版?我用的反權向思維
『叄』 如何判別欄位中是否包含了emojicon表情以及過濾相關內容
<span style="font-family: Arial, Helvetica, sans-serif;">過濾該表情</span>
[java] view plain
public static String filterEmoji(String source) {
if (!containsEmoji(source)) {
return source;// 如果不包含,直接返回
}
StringBuilder buf = null;
int len = source.length();
for (int i = 0; i < len; i++) {
char codePoint = source.charAt(i);
if (!isEmojiCharacter(codePoint)) {
if (buf == null) {
buf = new StringBuilder(source.length());
}
buf.append(codePoint);
} else {
}
}
if (buf == null) {
return "";
} else {
if (buf.length() == len) {// 這里的意義在於盡可能少的toString,因為會重新生成字元串
buf = null;
return source;
} else {
return buf.toString();
}
}
}
[java] view plain
// 判別是否包含Emoji表情
private static boolean containsEmoji(String str) {
int len = str.length();
for (int i = 0; i < len; i++) {
if (isEmojiCharacter(str.charAt(i))) {
return true;
}
}
return false;
}
private static boolean isEmojiCharacter(char codePoint) {
return !((codePoint == 0x0) ||
(codePoint == 0x9) ||
(codePoint == 0xA) ||
(codePoint == 0xD) ||
((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
((codePoint >= 0x10000) && (codePoint <= 0x10FFFF)));
}
『肆』 如何轉義emoji表情,讓它可以存入utf8的資料庫
unicode emoji是4個位元組的,存不進里,找到一個轉義的庫code.iamcal.com/php/emoji/,但是轉為Unicode之後,還是4個位元組,一樣存不進,應該說根本沒轉。轉為其他格式的emoji又怕以後新增了表情不好做,你們在不改資料庫編碼的前提下,是怎麼弄的?
方法1:base_encode64
這種方法是可以,但是舊數據沒有經過encode操作,取數據的時候如果統一進行decode的話,舊數據會丟失的。
方法2:urlencode
這個似乎可以,對沒有經過encode的數據進行decode也不會有影響,而且多次decode似乎也不會有影響。你們說這個方法有缺陷嗎?
=======================
一個發現,微信獲取用戶基本信息的時候,笑哭那個表情print_r出的是\ud83d\ude02,而我存儲的時候,報錯說這個 \xF0\x9F\x98\x82 值不能存儲,請問這是怎麼回事,自動轉碼了,轉成的這是什麼?是微信轉碼過了嗎?
=======================
方法3:最後採用了下面採納的那個方法,因為我覺得它有下面幾個優點:
1、那個方法只轉換表情,不會轉換中文,所以數據還是直接可讀的
資料庫中存儲起來是這樣的, 後面的\ud83d\udca5可以隨意復制粘貼,而顯示出來是這樣的,
2、不會把表情轉換為其它標准,只有一個簡單的,固定的轉換演算法,也就是說不需要一個表情庫來對照著轉換,所以以後其它人要使用這個數據的時候,也很容易知道每個表情是對應的哪個。就算蘋果大爺又增加了表情,也不需要做什麼額外的修改。
3、可以無限decode輸出的都是正確的內容。因為有的時候可能需要在一次請求中的兩個地方做decode,其它decode多次會把正確的數據改成其它數據,這個不會。
『伍』 android怎樣過濾字元串中的emoji表情
對於字元串處理,首選就是正則表達式去處理,而在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表情了
『陸』 如何將4位元組utf-8的emoji表情轉換為unicode字元編碼
1. Unicode是什麼
Unicode(中文:萬國碼、國際碼、統一碼、單一碼)是計算機科學領域里的一項業界標准。它對世界上大部分的文字系統進行了整理、編碼,使得電腦可以用更為簡單的方式來呈現和處理文字。
簡單說來,就是把世界上所有語言的字,加上所有能找到的符號(如高音譜號、麻將、emoji)用同一套編碼表示出來。
2. UTF-8是什麼
UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長度字元編碼。可變長度的意思在於,如果能使用1位元組編碼,UTF-8絕對不會使用2位元組去表示。舉個例子,UTF-8的1位元組部分和ASCII碼是相同的。所以表示'A'這個字元的時候,UTF-8與ASCII碼不僅編碼相同,而且都是只使用1位元組。
3. Character Set和Collation是什麼
Character Set是一套符號以及編碼。Collation是character set的排序方法。在中文版的MySQL中,character set被翻譯為「字元集」,collation被翻譯為「整理」。
舉個例子,UTF-8是character set,utf8_unicode_ci和utf8mb4_unicode_ci就是collation。
Collation的作用主要有二:字元排序與查找字元。
字元排序的作用是顯而易見的,不過還是要用幾個例子加以說明。比如要比較a和b的大小,因為在26個英文字母裡面,a在b前,所以在編碼的時候,也把a放在b前面。這樣就產生了第一種排序方式,通過字元編碼的大小來排序。而在中文裡面,「年」和「日」的排序,除了按照字元編碼大小,還可以有另外一些標准。比如可以按照筆畫序,「年」的第一筆是丿,「日」的第一筆是丨,而丨是排在丿前的,所以就將「日」排在前面;也可以按拼音序,「年」是n開頭,「日」是r開頭,於是把「年」排在前面。除此以外,還可以定義部首序、筆畫數序等等,而不同的排序方法會有不同的結果。英文也有大小寫敏感與不敏感的排序方式。種種不同的排序方式,就形成了不同的collations。
Collation的第二個作用則是查找字元是否在一個字元集裡面。既然是一個有序的集合,則可以快速地通過一個編碼值確定一個字元是否在集合內。這個特性是我們在不知不覺中使用的。比如使用中文輸入法,就是通過輸入法找到一個編碼,通過collation把它查找出來的。
4. Unicode再深入:Plane和中日韓越統一表意文字
utf8_unicode_ci和utf8mb4_unicode_ci這兩個collations都是基於UTF-8編碼的,但排序方面或多或少會有差別。可是更大的差別是它查找字元的集合。這需要提到一個Unicode的概念:Plane。
4.1. Plane
Plane中文譯作「Unicode平面字元映射」,不過我們還是叫它plane好啦。目前的Unicode字元分為17個planes,而每個plane擁有65536(即2^16)個代碼點。可以認為一個plane就是一個范圍的編碼。
Plane 0也叫做BMP(Basic Multilingual Plane,基本多文種平面),存放著世界上各種語言與標記中最常用的字元。
Plane 1也叫做SMP(Supplementary Multilingual Plane,多文種補充平面),放著表情符號(emoji)、字母與數學符號、音樂符號、太玄經(太極符號)、裝飾符號、撲克牌、麻將符號、箭頭擴展和一些世界上各種語言不太常用的文字等等。
Plane 2也叫做SIP(Supplementary Ideographic Plane,表意文字補充平面),用於存放統一漢字(見4.2)的一些罕用字與漢藏語系其他語言的用字(如粵語用字)。
4.2. 統一漢字的分布
對於統一漢字(中日韓越統一表意文字,CJKV Unified Ideographs)來說,BMP存放著最初的版本(也是最常用字)與擴展A區的漢字。擴展B區到即將到來的擴展E區都放在SIP中。
在這些區中,除了獨立字源的字,還有同一個字源或部首不同的變體或寫法。比如「戶」的第一筆,中國大陸與香港寫作「戶」,台灣寫作「戶」,日本則寫作「戸」。這些差異也會在Unicode中用三個不同的編碼去表示。所以B區到E區有不少此種字體。
舉些B區的例子。網路上之前流行的「不會功夫不要艹我」被寫成「「xx巭嫑莪」,其中「xx」這個字就是在B區。而粵語「x雞」(閹雞)、「x完松」(和一個人發生關系後棄之而去)兩個詞的首字也是在B區。
5. utf8_unicode_ci和utf8mb4_unicode_ci的異同
這兩種collations所對應的字元都是UTF-8編碼的一個子集。utf8_unicode_ci最多能找到3個位元組的Unicode編碼,而utf8mb4_unicode_ci則能找到4個位元組的編碼。由於調整後的UTF-8編碼格式規定最多使用4位元組(原來是6位元組)編碼,所以utf8mb4系列可以說是覆蓋了整個Unicode編碼。
由於utf8_unicode_ci最多能找到3個位元組的編碼,意味著它只支持BMP中的字元,對於SMP與SIP以及其他頭一位元組不為0x00、需要4位元組編碼的planes來說,utf8_unicode_ci這種collation是無法支持。當使用4位元組的字元(如emoji與B區以後的統一漢字)對使用此種collation的欄位進行增刪查改時,資料庫會報一個非法字元的異常。而utf8mb4則沒有此問題。由此也看出,utf8mb4_unicode_ci是utf8_unicode_ci的超集。
6. utf8mb4_unicode_ci的優缺點
utf8mb4系列的Collation在MySQL 5.5以上開始支持。相比起utf8_unicode_ci,它有如下的特性:
1) 在數據表中,對於BMP中的字元(最多使用3位元組的字元,最常用的字元),兩種collations具有完全相同的存儲特性:相同的碼值,相同的編碼方式,相同的存儲長度。不會增加任何的存儲開銷。
2) 在數據表中,對於其他plains的字元,utf8系列的collation根本不能存儲,而utf8mb4系列的collations則可以存儲。
3) 在數據表中,對於變長的欄位(如VARCHAR2,TEXT),utf8mb4最大可存儲的字元可能少於utf8系列的collation。
4) 在索引中,對於文本類型的欄位,utf8mb4可索引的字元少於utf8系列的collations。如InnoDB的索引最多使用767位元組。如果使用utf8mb4,每一個字元都會預留4位元組做索引,而utf8則預留3位元組。故此前者是191個字元,後者是255個字元。
5) 由於4)的原因,加上字元集大,utf8mb4的性能可能比utf8系列的collations低。
6) 若升級前的欄位做了索引,需要把索引字元限制在191字元或以內。
7. 當前系統用哪個好
在當前的系統,全部都使用utf8_unicode_ci這種collation。但是在存儲網頁標題時,標題帶有SMP或者SIP的字元,如emoji、粵語字,會引發資料庫寫入異常。於是,就有兩種解決方向:
1) 扔掉。
1.1) 扔掉或截斷引發異常的字。採取此種方法,需要對每一個標題進行掃描。
1.2) 扔掉整條記錄。可以採取掃描法,或者扔掉引發異常的記錄。
2) 升級到utf8mb4。會略為降低資料庫性能。
7.1. 性能考慮
首先對於寫入性能,查找字體的性能損耗由於在寫入前字元都已經變成編碼,基本可以忽略。對於網路傳輸的性能,則需要繼續查找相關資料繼續查證。但初步估計由於目前資料庫在本地,故此這部分開銷的增長不太明顯。
而對於索引的性能,由於網頁標題這一欄位沒有做索引,在可預見的將來也未有此計劃,故此沒有性能的損耗,也沒有升級兼容性的擔心。
況且,倘若走扔掉數據的方向,若採取掃描法,則需要付出掃描的開銷。若採取扔掉記錄法,則會先觸發事務回滾,其他記錄需要下次重新寫入。而且當一批記錄寫入時有k個記錄引發異常,則需要回滾與重試k次,除非使用掃描法預先掃描出這些異常的記錄。但這也會引入額外的程序與資料庫開銷。若不使用事務,則資料庫總體寫入性能會大為降低。
雖然沒有實測過,但從感覺上來定性判斷,似乎扔掉記錄比升級collation帶來的性能退化要大。
7.2. 存儲空間考慮
當前的網頁標題是使用VARCHAR2存儲。對於現在可用的、常見的BMP字元,不會引入額外的存儲開銷。BMP字元在VARCHAR的類型下不會為每一字元引入額外33%的空間開銷。反之,定長的CHAR就會引入這種額外開銷。
7.3. 目標數據考慮
網頁標題作為以後特徵分析的數據源。在分析需求完全沒有確定的情況下,我認為扔掉任何數據都是不宜採取的辦法,特別是整條記錄扔掉更是不推薦。因為現階段我們沒有一套標准去判定何為有效數據、何為無效數據。有可能引發異常的那部分數據確實是沒用的數據,也有可能那部分人群更傾向於在我們平台上活躍使用。既然各種可能性都存在,我們主動放棄一部分可能性,似乎不太恰當。
7.4. API設計與兼容性考慮
由於utf8_unicode_ci與utf8mb4_unicode_ci都是使用UTF-8編碼,所以對於JAVA,使用MyBatis生成的代碼是一樣的,都是使用String類型。這點已經實測過。加上這兩種collations在BMP中的編碼完全一致,所以使用3位元組與4位元組的系統,對於BMP中的字元都是完全兼容、正常顯示的。而對於3位元組的系統,4位元組的字元一般會顯示成一個方框,或者在一個方框中有幾個小數字,不會引發系統異常。
8. 總結
誠然,emoji對分詞分析目前來說還沒有什麼效果,粵語詞而且在SIP中也只是其中一部分,也不知道有多少日本動漫或者愛情動作片的網頁會遇到這些生僻字,音樂符號也少人用,太極符號也不是每次都出現,一些數學增補的字元與箭頭增補圖案也不是每個人都會用。這些加起來可能不知夠不夠全部的千分之一。
但是倘若每一兩個小時就會由於字元不能寫入,引發資料庫的異常。通過上面的分析,我認為增加這種兼容性帶來的成本是可以接受的。
故此,我建議使用升級的方法,兼容所有Unicode字元。
『柒』 求php過濾ios的Emoji表情的方法,如果字元串中包含Emoji表情就刪除。
網上已經有開源的了!http://code.iamcal.com/php/emoji/ 你參考下
iOS 5.0之前,蘋果都是採用3個位元組來承接 emoji 表情,Java 的普通 char 可以支持顯示。但 iOS 5.0 之後, 蘋果升級了系統自帶的 emoji 表情輸入法,用的 Unicode 6 標准來統一,是採用4個 bytes 來承接一個 emoji 表情。如果不做處理的話,這種表情直接存儲到 mysql5.5 以下的資料庫是會報錯的。就像這兩個表情一樣:口口, 在 Windows 8 以下估計都不支持顯示,可能會顯示成框框,可能壓根就是空白, 你可以在 Mac 中使用Safari 瀏覽器中,就可以看到。經過測試,在 Mac 就算用 Chrome 瀏覽器(Version 25.0.1364.172)也是不行的。
這種數據在 Mysql 5.5 之前,UTF-8 支持1-3個位元組的編碼,從 Mysql5.5 開始後,可以支持4個位元組的 UTF 編碼,但要特殊標記。修改 Mysql 相應存儲欄位為 utf8mb4 。修改語句如下:
1 ALTER TABLE table_name
2 MODIFY COLUMN content varchar(500) CHARACTER
3 SET utf8mb4 COLLATE utf8mb4_unicode_ci
4 DEFAULT NULL COMMENT 'content of message';
在某種業務情景下,我們可以選擇過濾掉這種「非法」的字元。我採用的方式是,在字元上面做操作,下面是Java示例代碼,核心的代碼附上,應該是 無法直接下載就能夠編譯,你得小小的做一些微調,沒有額外的依賴:
01 public class EmojiFilter {
02
03 /**
04 * 檢測是否有emoji字元
05 * @param source
06 * @return 一旦含有就拋出
07 */
08 public static boolean containsEmoji(String source) {
09 if (StringUtils.isBlank(source)) {
10 return false;
11 }
12
13 int len = source.length();
14
15 for (int i = 0; i < len; i++) {
16 char codePoint = source.charAt(i);
17
18 if (isEmojiCharacter(codePoint)) {
19 //do nothing,判斷到了這里表明,確認有表情字元
20 return true;
21 }
22 }
23
24 return false;
25 }
26
27 private static boolean isEmojiCharacter(char codePoint) {
28 return (codePoint == 0x0) ||
29 (codePoint == 0x9) ||
30 (codePoint == 0xA) ||
31 (codePoint == 0xD) ||
32 ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) ||
33 ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) ||
34 ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
35 }
36
37 /**
38 * 過濾emoji 或者 其他非文字類型的字元
39 * @param source
40 * @return
41 */
42 public static String filterEmoji(String source) {
43
44 if (!containsEmoji(source)) {
45 return source;//如果不包含,直接返回
46 }
47 //到這里鐵定包含
48 StringBuilder buf = null;
49
50 int len = source.length();
51
52 for (int i = 0; i < len; i++) {
53 char codePoint = source.charAt(i);
54
55 if (isEmojiCharacter(codePoint)) {
56 if (buf == null) {
57 buf = new StringBuilder(source.length());
58 }
59
60 buf.append(codePoint);
61 } else {
62 }
63 }
64
65 if (buf == null) {
66 return source;//如果沒有找到 emoji表情,則返回源字元串
67 } else {
68 if (buf.length() == len) {//這里的意義在於盡可能少的toString,因為會重新生成字元串
69 buf = null;
70 return source;
71 } else {
72 return buf.toString();
73 }
74 }
75
76 }
77 }
還有優化的空間,但是已經能夠滿足大多數情況的需求,附上單元測試(JUnit4):
01 public class EmojiFilterTest {
02
03
04 /**
05 * 測試emoji表情
06 */
07 @Test
08 public void fileterEmoji() {
09 String s = "<body>口口213這是一個有各種內容的消息, Hia Hia Hia !!!! xxxx@@@...*)!" +
10 "(@*$&@(!)@*)!&$!)@^%@(!. 口口口], ";
11 String c = Utils.filterEmoji(s);
12 assertFalse(s.equals(c));
13 String expected = "<body>213這是一個有各種內容的消息, Hia Hia Hia !!!! xxxx@@@...*)" +
14 "!(@*$&@(!)@*)!&$!)@^%@(!. ], ";
15 assertEquals(expected, c);
16 // assertSame(c, expected);
17 assertSame(expected, "<body>213這是一個有各種內容的消息, Hia Hia Hia !!!! xxxx@@@...*)" +
18 "!(@*$&@(!)@*)!&$!)@^%@(!. ], ");
19 assertSame(c, Utils.filterEmoji(c));
20 }
21
22 }
『捌』 如何處理emoji等4位元組的Unicode字元
emoji對分詞分析目前來說還沒有什麼效果,粵語詞而且在SIP中也只是其中一部分,也內不知道有多少日本動漫或者愛容情動作片的網頁會遇到這些生僻字,音樂符號也少人用,太極符號也不是每次都出現,一些數學增補的字元與箭頭增補圖案也不是每個人都會用。這些加起來可能不知夠不夠全部的千分之一。
但是倘若每一兩個小時就會由於字元不能寫入,引發資料庫的異常。通過上面的分析,我認為增加這種兼容性帶來的成本是可以接受的。
故此,我建議使用升級的方法,兼容所有Unicode字元。
『玖』 怎麼判斷emoji表情字元
系統的表情都對應一個unicode編碼,對應的表用Softbank列。
讀到內存中,判斷內存中的是不是表情的unicode碼,是的話就過濾掉,這應該就行了。
『拾』 怎麼將emoji符號全部倒出來 並且和相應的unicode碼對應起來
: utf-8的「emoji表情」估計在Unicode中並不存在,因此是無法轉換的,否則直接採用Unicode的圖形符號就可以了。