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

資訊專欄INFORMATION COLUMN

前端字符編碼小結(jié)

gitmilk / 2134人閱讀

摘要:導(dǎo)語本文源于微信游戲春節(jié)王者搖心愿活動(dòng)英雄語音祝福自定義輸入模塊開發(fā)過程,對(duì)踩過的前端字符編碼的坑進(jìn)行記錄總結(jié)。只規(guī)定了字符編碼,而并沒有規(guī)定具體的編碼方式。

導(dǎo)語
本文源于微信游戲春節(jié)王者搖心愿活動(dòng)英雄語音祝福自定義輸入模塊開發(fā)過程,對(duì)踩過的前端字符編碼的坑進(jìn)行記錄總結(jié)。
Unicode 字符
Unicode(中文:萬國碼、國際碼、統(tǒng)一碼、單一碼)是計(jì)算機(jī)科學(xué)領(lǐng)域里的一項(xiàng)業(yè)界標(biāo)準(zhǔn)。它對(duì)世界上大部分的文字系統(tǒng)進(jìn)行了整理、編碼,使得電腦可以用更為簡(jiǎn)單的方式來呈現(xiàn)和處理文字。

簡(jiǎn)單地來說,Unicode 是一種字符編碼,它規(guī)定用一個(gè)碼點(diǎn)表示一個(gè)字符,其范圍為 U+0000~ U+10FFFF , 可以表示超過100萬個(gè)符號(hào)。Unicode 分成17個(gè)平面,其中第1個(gè)平面稱謂基本平面(也稱 BMP),其范圍為 U+0000~ U+FFFF,另外16個(gè)平面稱之為輔助平面,每個(gè)輔助平面擁有65536(即 2^16)個(gè)字符。

Unicode 只規(guī)定了字符編碼,而并沒有規(guī)定具體的編碼方式。因此就產(chǎn)生了不同的編碼方式,包括 UTF-8、UTF-16、UTF-32 等等。

UTF-16

本文主要介紹 UTF-16 編碼,不涉及 UTF-8、UTF-32 等其他編碼方式,需要擴(kuò)展閱讀請(qǐng)自行查閱。
UTF-16 是一種變長的編碼方式,可以用2個(gè)字節(jié)或者4個(gè)字節(jié)來編碼 Unicode 字符。UTF-16 使用兩個(gè)字節(jié)編碼 Unicode 字符中的基本平面的字符,使用 4 個(gè)字節(jié)編碼 Unicode 字符中的輔助平面的字符。

UTF-16 使用變長字節(jié)的編碼方式,那么如何判斷一個(gè)字符是基本平面字符還是輔助平面字符?
UTF-16 規(guī)定了BMP中,從 U+D800U+DFFF 之間BMP的區(qū)段是永久保留不映射到字符,可以利用這段區(qū)間來編碼輔助平面的字符。
簡(jiǎn)單來說,從左到右掃描,發(fā)現(xiàn)前兩個(gè)字節(jié)不在 U+D800U+DFFF 之UTF間,則可認(rèn)定這兩個(gè)字節(jié)組成了一個(gè)基本平面的字符,發(fā)現(xiàn)前兩個(gè)字節(jié)處于 U+D800U+DFFF 之間,則需要讀取下兩個(gè)字節(jié),拼湊成四個(gè)字節(jié)組成一個(gè)輔助平面的字符。

前面提到輔助平面有16(即 2^4)個(gè),每個(gè)輔助平面擁有65536(即 2^16)個(gè)字符,因此輔助平面共有 2^20個(gè)字符,也就是說需要 20 位二進(jìn)制位來對(duì)應(yīng)這些字符。

16 * 65536 = 2^4 * 2^16 = 2^20

U+D800U+DFFF 之間剛好有 2^11 個(gè)碼元,因此 UTF-16 使用 U+D800U+DBFF 之間(共有2^10個(gè))碼元作為高位, U+DC00U+DFFF 之間(共有 2^10 個(gè))作為低位,這樣子高低位 4 個(gè)字節(jié)組成的編碼方式(代理對(duì))就可以表示一個(gè)輔助平面的字符了。

其中,輔助平面字符 Unicode 到 UTF-16 代理對(duì)的轉(zhuǎn)換規(guī)則如下( c 表示 Unicode 的碼元,H 表示代理對(duì)的高位字節(jié),L 表示代理對(duì)的低位字節(jié)):

H = Math.floor((c - 0x10000) / 0x400) + 0xD800 
L = (c - 0x10000) % 0x400 + 0xDC00

以上面的音樂字符為例,其 Unicode 字符的碼元為 U+1F3B6,可以通過 https://codepoints.net/ 查詢到對(duì)應(yīng)字符信息

> H = Math.floor((0x1F3B6 - 0x10000) / 0x400) + 0xD800 
0xd83c

> L = (0x1F3B6 - 0x10000) % 0x400 + 0xDC00
0xdfb6

通過上面的轉(zhuǎn)換規(guī)則可以算出其代理對(duì)為 ud83cudfb6

UCS-2

UCS-2 是 UTF-16 未出世之前的一種編碼方式,可以簡(jiǎn)單理解為 UTF-16的子集。它采用定長2字節(jié)編碼,因此只能表示基本平面的字符,對(duì)于輔助平面字符,它只能理解為這是 “兩個(gè)基本平面字符” ,無法正常表示。

javascript的編碼方式

好了,進(jìn)入正題了。前面講了 UTF-16 和 UCS-2,那么 javascript 到底是采用什么編碼的呢?
這個(gè)要分情況來講,javascript 引擎采用 UTF-16 編碼,而 javascript 語言本身的設(shè)計(jì)是采用 UCS-2 編碼方式
因此,當(dāng)我們使用 UCS-2 編碼方式設(shè)計(jì)的 javascript 接口來處理 UTF-16 編碼的字符,就會(huì)出現(xiàn)很多問題。
比如:

那么如何解決這兩者編碼方式不一致造成的問題呢,有兩種方式:

ES6

新版本的ECMA Script提供了新的API來正確處理字符

正則

利用正則表達(dá)式對(duì)其修正(項(xiàng)目也是采用這種方式)

var regexAstralSymbols = /[uD800-uDBFF][uDC00-uDFFF]/g
// 獲取字符的長度
function countSymbols(string) {
    return string
        // 把代理對(duì)改為一個(gè)BMP的字符.
        .replace(regexAstralSymbols, "_")
        // …這時(shí)候取長度就妥妥的啦.
        .length;
}

// 獲取前6個(gè)字符
function sliceSymbols(str, limit) {
    var output = [];
    var index = 0;
    var oldStr = str;
    str = str.replace(regexAstralSymbols, function(input, offset, match) {
        if( offset > index ) {
            output = output.concat(match.slice(index, offset).split(""));
        }
        index = offset + input.length;
        output.push(input)
        return "";
    });

    if( index < oldStr.length  ) {
        output = output.concat(oldStr.slice(index, oldStr.length).split(""));
    }
    return output.slice(0, limit).join("");
}

實(shí)現(xiàn)效果如下:

上面的解決方法基本可以解決大部分的字符問題,但是在遇到某些emoji表情依然會(huì)有些問題。

emoji

emoji表情符號(hào)是一種象形文字(圖片符號(hào)),通常以豐富多彩的形式呈現(xiàn)并在文本中以內(nèi)聯(lián)形式使用,起源于日本。Unicode 對(duì) emoji 表情做了劃分范圍,大部分屬于輔助平面字符,目前 Unicode 中收錄的 emoji 表情達(dá)到了 2700多個(gè)。因此,在大部分情況下,使用UTF-16的代理對(duì)來處理emoji 表情是沒有問題。但在 emoji 表情中,還存在著一些字符(Emoji Sequences),它們沒有顯示的樣式,主要起著連接、控制等作用。目前有下面幾種:

控制符

, 作用是讓基礎(chǔ)Emoji 變成更接近文本樣式( text-style )。
, 作用則是讓基礎(chǔ)Emoji 變成更接近Emoji樣式( emoji-style )。

零寬連接符

emoji 除了單個(gè) emoji 符號(hào),還可以通過零寬連接符將多個(gè) emoji 連接成一個(gè) emoji。比如 ud83dudc68是表示一個(gè) man,ud83cudf93表示一個(gè)學(xué)士帽,這兩個(gè)通過零寬連接符連接起來 ud83dudc68u200dud83cudf93就表示一個(gè)男學(xué)生了。

因此,為了解決emoji這些Emoji Sequences,將正則進(jìn)行擴(kuò)展:

var regexAstralSymbols = /[uD800-uDBFF][uDC00-uDFFF][u200D|uFE0F|uFE0E]|[uD800-uDBFF][uDC00-uDFFF]/g;

除了以上兩種比較常見的 Emoji Sequences,其實(shí)還有 Keycap Sequence, Flag Sequence, Tag Sequence, Modifier Sequence等字符,可以參考這里。

參考鏈接

https://mathiasbynens.be/note...
https://mathiasbynens.be/note...
https://codepoints.net/
http://www.alloyteam.com/2016...
http://unicode.org/emoji/
https://unicode.org/emoji/cha...
http://unicode.org/emoji/char...

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/92973.html

相關(guān)文章

  • js獲取字符串字節(jié)數(shù)方法小結(jié)

    摘要:具體如下大家都知道,獲取字符串的長度可用來獲取,那么獲取這段字符串的字節(jié)數(shù)呢英文字母肯定和字節(jié)數(shù)都一樣都是而中文字節(jié)數(shù)因此,需要作的就是把中文字符的字節(jié)數(shù)計(jì)算出來。 這篇文章主要介紹了js獲取字符串字節(jié)數(shù)方法,實(shí)例總結(jié)了javascript字符串長度計(jì)算的相關(guān)技巧,需要的朋友可以> 參考下 本文實(shí)例講述js獲取字符串字節(jié)數(shù)的方法。分享給大家供大家參考。具體如下: 大家都知道,獲取字符串...

    elisa.yang 評(píng)論0 收藏0
  • 字符編碼(一)

    摘要:最近在看書的時(shí)候突然糾結(jié)于相關(guān)字符編碼,查了一些資料,并寫了這篇文章,順帶做下筆記,希望能幫到一些人。解決傳統(tǒng)的字符編碼方案的局限。 最近在看書的時(shí)候突然糾結(jié)于Unicode相關(guān)字符編碼,查了一些資料,并寫了這篇文章,順帶做下筆記,希望能幫到一些人。文章如果有寫的不妥的或者不正確的地方還請(qǐng)大家糾正。 Unicode 編碼 Unicode是一個(gè)符號(hào)集,它對(duì)世界上大部分的文字系統(tǒng)進(jìn)行了整理...

    UnixAgain 評(píng)論0 收藏0
  • PHP基礎(chǔ)知識(shí)小結(jié)

    原始數(shù)據(jù)類型(9種) 基本數(shù)據(jù)類型: 整形(integer)、浮點(diǎn)型(float)、字符串(string)、布爾型(boolean) 復(fù)合數(shù)據(jù)類型:數(shù)組(array)、對(duì)象(object)、callable(可調(diào)用) 特殊數(shù)據(jù)類型:資源類型(resource) 和 NULL 變量相關(guān)處理函數(shù) is_bool($var)????????判斷是否為布爾型 is_int($var)????...

    RancherLabs 評(píng)論0 收藏0
  • 前端入門小結(jié)

    摘要:實(shí)現(xiàn)了搜索這一功能,接下來就是要把這一部分嵌入到一個(gè)平臺(tái),因此我開始接觸編程以及前端。之前我對(duì)前端幾乎沒有什么了解,因此這一周除了體檢被檢查出來早搏參加入學(xué)典禮之外,就是在琢磨,,了,并結(jié)合需求開發(fā)了網(wǎng)站的一部分。 今年暑假大部分時(shí)間是在要學(xué)校,前一階段一直在學(xué)習(xí)Scala和理解Spark,但是苦于沒有實(shí)際上手的項(xiàng)目,盡管看了不少論文和書,但不敢說自己理解的有多深刻,所以我打算暫時(shí)擱置...

    chengtao1633 評(píng)論0 收藏0
  • 第十一章-IO流#yyds干貨盤點(diǎn)#

    摘要:是一個(gè)系統(tǒng)支持的所有字符的集合,包括各國家文字標(biāo)點(diǎn)符號(hào)圖形符號(hào)數(shù)字等字符集簡(jiǎn)體中文碼表。支持中國國內(nèi)少數(shù)民族的文字,同時(shí)支持繁體漢字以及日韓漢字等字符集為表達(dá)任意語言的任意字符而設(shè)計(jì),是業(yè)界的一種標(biāo)準(zhǔn),也稱為統(tǒng)一碼標(biāo)準(zhǔn)萬國碼。 1 File1.1 File類的概述和構(gòu)造方法File: 它是文件和目錄路徑名的抽象...

    不知名網(wǎng)友 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<