国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Emoji的編碼以及常見問題處理

wemall / 1562人閱讀

摘要:題外話補(bǔ)充一點是一種字符編碼方法,它是由國際組織設(shè)計,可以容納全世界所有語言文字的編碼方案。帶有的字符串截取在這類編程語言中一個中文字符的長度為,但是對大部分的并非全部取長度則是。

我在虎嗅上看過一篇關(guān)于Emoji的趣聞, 特別有意思, 在這里跟大家分享一下。里面提到了Emoji是怎么誕生的。

1999年前后,日本一個名叫栗田穰崇的年輕人,和許多直男一樣, 給女友發(fā)的短信經(jīng)常會被誤解。比如,“知道了”被解讀成“生氣了”、“不耐煩了”,隨后引發(fā)冷戰(zhàn)。 于是少年栗田想:“如果能在文字里插入一些表情符號來表達(dá)感情,大家應(yīng)該會需要吧!”
原始的Emoji就這么誕生了。

Emoji極大地豐富了我們的生活和通訊交流。Emoji誕生自程序員,但反過來對程序員也造成過一些困擾。
尤其對于面向C端的產(chǎn)品開發(fā)者, 用戶越來越習(xí)慣于輸入Emoji, 因此處理字符時遇到Emoji也只會越來越頻繁。

Emoji的編碼

Emoji字符是Unicode字符集中一部分. 特定形象的Emoji表情符號對應(yīng)到特定的Unicode字節(jié)。
常見的Emoji表情符號在Unicode字符集中的范圍和具體的字節(jié)映射關(guān)系, 可通過Emoji Unicode Tables查看到。

有意思的是, 在Emoji Unicode Tables表中,還給出了同一個Emoji表情在不同系統(tǒng)中的字體(是字體沒錯, Emoji的樣式可通過字體文件改變)。

關(guān)于Emoji的最權(quán)威資料, 可以在Unicode? Emoji Charts上查閱到。
截止我寫這篇文章的時刻, Emoji Charts 的最新版本是v3.0, v4.0還只是處于Beta階段。

題外話補(bǔ)充一點: Unicode是一種字符編碼方法,它是由國際組織設(shè)計,可以容納全世界所有語言文字的編碼方案。
我們所知道的UTF-8、UTF-16等編碼, 是對Unicode的不同實現(xiàn)方式。
如果要深入了解更多關(guān)于ASCII、Unicode、UTF-8、gb2312、gbk等編碼的相關(guān)知識,在這里強(qiáng)烈推薦幾篇文章,講得非常好。

字符編碼筆記:ASCII,Unicode和UTF-8

程序員趣味讀物:談?wù)刄nicode編碼

一些特殊的Emoji

在眾多Emoji中, 有一些特殊的Emoji 并沒有顯示的樣式, 只是起到了控制的作用。這些控制型的Emoji 與基礎(chǔ)Emoji 出現(xiàn)在一起, 可以展示更多的樣式。

比如 "變量選擇器-15"(VARIATION SELECTOR-15, 簡寫VS-15): , 作用是讓基礎(chǔ)Emoji 變成更接近文本樣式(text-style);
而 "變量選擇器-16"(VARIATION SELECTOR-16, 簡寫VS-16): , 作用則是讓基礎(chǔ)Emoji 變成更接近Emoji樣式(emoji-style).

VS-15 和 VS-16 加在基礎(chǔ)Emoji字符的后面, 可以起到控制作用(前提是必須系統(tǒng)支持, 否則會被忽略)。

用一段Python代碼來演示該例子:

# -*- coding: utf-8 -*-
# more info to see https://en.wikipedia.org/wiki/Emoji
# 符號分別是上圖(截圖自wiki)中的符號, 最后再加上一個“狗”的Emoji
sample_list = [u"u2139", u"u231B", u"u26A0", u"u2712", u"u2764", u"U0001F004", u"U0001F21A", u"U0001f436", ]

# 輸出原樣式
for code in sample_list:
    print code,
print
print "-" * 20
# 后面加上VS-15
for code in sample_list:
    print (code + u"uFE0E"),
print
print "-" * 20
# 后面加上VS-16
for code in sample_list:
    print (code + u"uFE0F"),

其輸出如下圖, 第一行是原樣式,第二行是加上VS-15后的樣式,第三行是加上VS-16后的樣式:

另外, 還有一些控制型的Emoji, 可以對人體膚色進(jìn)行改變,改變對象僅限于"表示人身體部位的Emoji".
它們分別是: 共五個, 分別簡稱為: FITZ-1-2, FITZ-3, FITZ-4, FITZ-5, FITZ-6.

還有一個特殊的控制符: (ZERO WIDTH JOINER, 簡寫ZWJ), 起到了連接Emoji的作用, 從而將多個Emoji變成一個Emoji來顯示. 同樣,前提是必須系統(tǒng)支持, 否則會被忽略.

使用Python代碼演示 FITZ-*ZWJ:

# -*- coding: utf-8 -*-
# more info to see https://en.wikipedia.org/wiki/Emoji

# man_list 分別是: 男孩  女孩  男人  女人
man_list = [u"U0001F466", u"U0001F467", u"U0001F468", u"U0001F469"]
# skin_color_list 分別是: 空字符串,表示默認(rèn)  白種人 -->(不斷加深膚色)  黑種人
skin_color_list = ["", u"U0001F3FB", u"U0001F3FC", u"U0001F3FD", u"U0001F3FE", u"U0001F3FF", ]
for man in man_list:
    for color in skin_color_list:
        print (man + color),
    print
    print "-" * 20

# Emoji的連接符  (英文名為: ZERO WIDTH JOINER, 簡寫ZWJ )
# 如果系統(tǒng)支持: 連接(男人 + ZWJ + 女人 + ZWJ + 女孩)
print u"U0001F468" + u"u200D" + u"U0001F469" + u"u200D" + u"U0001F467"
# 如果系統(tǒng)不支持: 連接(狗 + ZWJ + 貓 + ZWJ + 老鼠)
print u"U0001f436" + u"u200D" + u"U0001f431" + u"u200D" + u"U0001f42d"

其輸出如下圖:

以上內(nèi)容參考自維基百科

對Emoji 的介紹到該小節(jié)結(jié)束, 下面內(nèi)容是一些關(guān)于實際中可能遇到的技術(shù)問題的解決方法。

MySQL存儲Emoji

使用MySQL存儲Emoji, 只需要數(shù)據(jù)表的字符集為utf8mb4即可, 即CHARSET=utf8mb4.

如果想要知道你的MySQL數(shù)據(jù)庫是否支持utf8mb4編碼, 可通過show charset; 輸出當(dāng)前安裝的MySQL所支持的所有字符集, 查看輸出中是否包含有utf8mb4.

另外, 有一些比較老的業(yè)務(wù), 可能一開始設(shè)計時沒考慮到需要支持Emoji, 那就需要修改數(shù)據(jù)庫或數(shù)據(jù)表的字符集.

查看MySQL說支持的所有字符集
mysql> show charset;

查看某張表當(dāng)前的字符集
mysql> show create table ;

創(chuàng)建默認(rèn)字符集為utf8mb4的數(shù)據(jù)庫.在該數(shù)據(jù)庫中,如果創(chuàng)建表時是不指明字符集,則默認(rèn)utf8mb4.
mysql> create database default charset utf8mb4;

創(chuàng)建字符集為utf8mb4的表, 數(shù)據(jù)庫的默認(rèn)字符集非utf8mb4也沒問題.
mysql> create table `` (Column定義, Column定義, ...) DEFAULT CHARSET=utf8mb4;

修改已存在的數(shù)據(jù)庫的字符集
mysql> alter database  default charset = utf8mb4;

修改已存在的表的字符集
mysql> alter table  default charset = utf8mb4;


使用正則表達(dá)式匹配Emoji

很可惜, Emoji的范圍并沒有明確的定義。正如上面提到了,Emoji Charts目前最新版本是v3.0, 未來Emoji的范圍還會不斷擴(kuò)大。而且Emoji 在Unicode的分配中并不是連續(xù)的區(qū)間。

所以, 在這里我只能給出一個可行的匹配區(qū)間, 盡可能涵蓋了基本常見的Emoj。
該匹配區(qū)間中會包含一些未定義的字符, 可能在某些系統(tǒng)會有定義,但是在另外的系統(tǒng)中并沒有定義。畢竟Emoji是商業(yè)的產(chǎn)物。

該匹配規(guī)則區(qū)間參考了emoji-data.txt 和 Unicode? Technical Report #51, 如下:

 -       # symbols & pictographs
 -       # emoticons
 -       # transport & map symbols
  -        # other

下面使用Python代碼來演示如何使用正則表達(dá)式替換(或找出)字符串中的Emoji:

# -*- coding: utf-8 -*-
import re
try:
    # Wide UCS-4 build
    myre = re.compile(u"["
        u"U0001F300-U0001F64F"
        u"U0001F680-U0001F6FF"
        u"u2600-u2B55]+",
        re.UNICODE)
except re.error:
    # Narrow UCS-2 build
    myre = re.compile(u"("
        u"ud83c[udf00-udfff]|"
        u"ud83d[udc00-ude4fude80-udeff]|"
        u"[u2600-u2B55])+",
        re.UNICODE)

sss = u"I have a dog U0001f436 . You have a cat U0001f431 ! I smile U0001f601 to you!"
print myre.sub("[Emoji]", sss)  # 替換字符串中的Emoji
print myre.findall(sss)         # 找出字符串中的Emoji

輸出如下:

I have a dog [Emoji] . You have a cat [Emoji] ! I smile [Emoji] to you!
[u"U0001f436", u"U0001f431", u"U0001f601"]

上面例子中, 之所以使用try...except...來處理代碼, 是考慮到 UCS-2 (Narrow UCS-2 build) 和 UCS-4 (Wide UCS-4 build) 的區(qū)別.
該Demo例子參考了stackoverflow上的精彩回答, 解答了我對此的困惑。

關(guān)于UCS-2和UCS-4的區(qū)別, 在上面提到的擴(kuò)展閱讀程序員趣味讀物:談?wù)刄nicode編碼中有提到, 值得一看.

本文中使用到的示例代碼,可以在我的github下載到。

帶有Emoji的字符串截取

在Python、JavaScript 這類編程語言中, 一個中文字符的長度為1,但是對大部分的Emoji(并非全部), 取長度則是2。下面使用Python做演示。

以中文的"漢"字取長度為例,取長度為1:

>>>len(u"漢")
1

而對于Emoji,以(該Emoji是一只萌萌的狗)為例,取長度為2:

>>>len(u"U0001f436")
2

那么, 這就存在一個隱患, 在對字符串進(jìn)行截斷時可能從中間截斷, 導(dǎo)致該字符顯示為亂碼, 甚至引發(fā)報錯。

下面例子中, 對字符串進(jìn)行截取時,正好從的中間截斷了,出現(xiàn)了亂碼:

>>>u"這是一只可愛的狗狗U0001f436".__len__()
11
>>>u"這是一只可愛的狗狗U0001f436"[0:10]
這是一只可愛的狗狗???

實際場景中,對字符串進(jìn)行截斷是非常常見的需求,而且字符串往往可能是用戶高度自由的輸入內(nèi)容, 那么包含Emoji的可能性其實是很高的。
一個具體的場景就是: 你正在開發(fā)了一款社交APP, 允許用戶保存文字記錄, 然后在應(yīng)用的某個地方, 又需要顯示這些文字記錄的摘要,摘要只顯示用戶輸入的前100個字符, 超出部分用省略號表示。
這種情況下,就不可避免的可能發(fā)生Emoji在中間被截斷的問題。

解決方案也有多種:

全文進(jìn)行正則匹配, 去掉大部分Emoji, 但是文本長度過長的情況消耗太大, 不值得.

先截取前200個字符, 匹配去掉Emoji再截取100個字符. 貌似可行. 但如果極端條件下前200個字符都是Emoji怎么辦? 管他的.

運用上面提到的擴(kuò)展閱讀: 字符編碼筆記:ASCII,Unicode和UTF-8中提到的UTF-8的編碼規(guī)則, 對截斷后字符串的最后字符進(jìn)行檢查, 發(fā)現(xiàn)是截斷的字符即進(jìn)行剔除。該方案可行, 不過你需要自己去實現(xiàn)了。

允許一定概率出現(xiàn)亂碼, 亂碼就亂碼吧,概率不高,不影響主要體驗。將更多精力放在避免其他bug上吧。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/44315.html

相關(guān)文章

  • 那些年我們踩過亂碼坑

    摘要:因此導(dǎo)致亂碼的真正原因就是各平臺間對標(biāo)準(zhǔn)實現(xiàn)不一致包括實現(xiàn)的時間先后不同,以及所代表含義不同。日本幾家公司各自定義了一套標(biāo)準(zhǔn),用兩個字節(jié)表示符號,日本電腦系統(tǒng)的一種編碼編碼是從到。在上找到了與標(biāo)準(zhǔn)的對應(yīng)關(guān)系。 歡迎關(guān)注個人網(wǎng)站:http://www.iamaddy.net/2016/07/emoji-unicode-parser/ 前言 這是一個由亂碼引發(fā)的故事。抱歉我暫時找不到更加慘...

    jhhfft 評論0 收藏0
  • 前端字符編碼小結(jié)

    摘要:導(dǎo)語本文源于微信游戲春節(jié)王者搖心愿活動英雄語音祝福自定義輸入模塊開發(fā)過程,對踩過的前端字符編碼的坑進(jìn)行記錄總結(jié)。只規(guī)定了字符編碼,而并沒有規(guī)定具體的編碼方式。 導(dǎo)語 本文源于微信游戲春節(jié)王者搖心愿活動英雄語音祝福自定義輸入模塊開發(fā)過程,對踩過的前端字符編碼的坑進(jìn)行記錄總結(jié)。 Unicode 字符 Unicode(中文:萬國碼、國際碼、統(tǒng)一碼、單一碼)是計算機(jī)科學(xué)領(lǐng)域里的一項業(yè)界標(biāo)準(zhǔn)。它...

    gitmilk 評論0 收藏0
  • 每日 30 秒 ? 字符編碼排雷錄

    showImg(https://segmentfault.com/img/remote/1460000018653055?w=900&h=500); 簡介 字符編碼、字符長度錯誤、截取字符錯誤、UTF8、Unicode 計算機(jī)重重底層之下都是由 0 和 1 組合,但是你知道他們是怎么一步步變成字符串的嘛?在我們現(xiàn)實生活中最常見的例子可以通過 wo 在新華字典中找到 我 這個字。同樣計算機(jī)通過 0 ...

    mmy123456 評論0 收藏0
  • 微信nickname亂碼(emoji)及mysql編碼格式設(shè)置(utf8mb4)解決過程

    摘要:自己的練習(xí)項目中涉及保存微信的,之前一直正常使用,但是突然遇到一個之前沒有遇到的問題。經(jīng)過調(diào)試發(fā)現(xiàn)錯誤如下經(jīng)過仔細(xì)查看發(fā)現(xiàn)可以獲得的數(shù)據(jù),但是無法保存到數(shù)據(jù)庫,查看用戶的微信發(fā)現(xiàn)在中使用了字符。上查找發(fā)現(xiàn)主要解決方案就是的編碼設(shè)置由轉(zhuǎn)為。 自己的練習(xí)項目中涉及保存微信的nickname,之前一直正常使用,但是突然遇到一個之前沒有遇到的問題。經(jīng)過調(diào)試發(fā)現(xiàn)錯誤如下: Incorrect ...

    xiaotianyi 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<