lua 獲取UTF-8中文字符串長度-string.byte

目錄:

一. UTF-8編碼規(guī)則
1.1 UTF-8簡單描述
1.2 UTF-8的中文字符編碼如何生成
二宾茂、lua 獲取UTF-8字符串長度(含中文)
2.1 lua判斷字符是不是中文
2.2 如何取得字節(jié)ASCII碼 - string.byte()
2.3 字符是由幾個字節(jié)組成
2.4 獲取UTF-8字符串長度(含示例)


一性含、UTF-8編碼規(guī)則

1.1 UTF-8簡單描述

UTF-8 是 Unicode 的實現(xiàn)方式之一长捧,其對應(yīng)關(guān)系(編碼規(guī)則)如下表所示:

Unicode 可以容納100多萬個符號

Unicode符號范圍 UTF-8字節(jié)數(shù) UTF-8編碼方式(二進(jìn)制)
0000 0000-0000 007F (0-127) 1 0xxxxxxx
0000 0080-0000 07FF (128-2047) 2 110xxxxx 10xxxxxx
0000 0800-0000 FFFF (2048-65535) 3 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF (65536-1050623) 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

UTF-8 最大的一個特點成玫,就是它是一種變長的編碼方式萍歉。它可以使用1~4個字節(jié)表示一個符號磕道,根據(jù)不同的符號而變化字節(jié)長度膀哲。

  1. 對于單字節(jié)的符號损拢,字節(jié)的第一位設(shè)為0陌粹,后面7位為這個符號的 Unicode 碼。取值0-127福压,與標(biāo)準(zhǔn)ASCII 碼一一對應(yīng)掏秩。標(biāo)準(zhǔn)ASCII 碼表見附錄。
  2. 對于n字節(jié)的符號(n > 1)荆姆,第一個字節(jié)的前n位都設(shè)為1蒙幻,第n + 1位設(shè)為0,后面字節(jié)的前兩位一律設(shè)為10胆筒。剩下的沒有提及的二進(jìn)制位邮破,全部為這個符號的 Unicode 碼诈豌。

1.2 UTF-8的中文字符編碼如何生成

例如 將,兩個字從Unicode轉(zhuǎn)換為UTF-8:

  1. 中 : Unicode 是 0x4E2D(0100 1110 0010 1101),根據(jù)上表,處于第三行范圍內(nèi)抒和,UTF-8編碼需要三個字節(jié)矫渔,格式為 1110xxxx 10xxxxxx 10xxxxxx
    的Unicode 二進(jìn)制填充進(jìn)這個格式摧莽,得到 11100100 10111000 10101101庙洼,轉(zhuǎn)換為十進(jìn)制是 228,184镊辕,173
    print(string.char(228,184,173)) =>
  2. 龍 : Unicode 是 0x9F99 (1001 1111 1001 1001) 油够,同樣處于第三行范圍內(nèi)。
    UTF-8編碼為11101001 10111110 10011001(233征懈,190石咬,153)
    print(string.char(233,190,153)) =>
input.png
out.png

漢字Unicode碼從漢字對應(yīng)表中查找

二、lua 獲取UTF-8字符串長度(含中文)

到這里受裹,已經(jīng)知道UTF-8的字符碌补、中文是怎么生成的了,又出現(xiàn)了2個疑問:

  1. 在lua中怎么判斷一個字符是不是中文棉饶?
  2. 這個字符是由幾個字節(jié)組成厦章?

2.1 lua判斷字符是不是中文

通常來說,漢字范圍從0x4E00到0x9FA5照藻,轉(zhuǎn)換為UTF-8編碼為11100100 10111000 10000000(228, 184, 128) 到 11101001 10111110 10100101(233, 190, 165)
因此袜啃,中文UTF-8編碼用3個字節(jié)表示,要遵守格式:1110xxxx 10xxxxxx 10xxxxxx
即第一個字節(jié)的取值區(qū)間為 [11100000, 11110000) = [0xe0, 0xf0) = [224, 240) 左開右閉
后兩個字節(jié)的取值區(qū)間為[10000000, 10111111] = [0x80幸缕,0xbf] = [128, 191] 開區(qū)間

2.2 如何取得字節(jié)ASCII碼 - string.byte()

string.byte()
  • 原型:string.byte (s [, i [, j] ])
  • 解釋:函數(shù)返回字符s[i], s[i+1], ···, s[j]的內(nèi)部數(shù)字編碼(ASCII碼)群发,其中參數(shù)i的默認(rèn)值是1,而參數(shù)j的默認(rèn)值是i发乔。

2.3 字符是由幾個字節(jié)組成

讀取第一個字節(jié)熟妓,在以下區(qū)間的代表不同的字節(jié)數(shù):(有疑問看1.1表)

  1. [0, 0xc0) 表示這個字符僅由1個字節(jié)構(gòu)成
  2. [0xc0, 0xe0) 表示這個字符由2個字節(jié)構(gòu)成
  3. [0xe0, 0xf0) 表示這個字符由3個字節(jié)構(gòu)成
  4. [0xf0, 0xff) 表示這個字符由4個字節(jié)構(gòu)成
local function Bytes4Character(theByte)
    local seperate = {0, 0xc0, 0xe0, 0xf0}
    for i = #seperate, 1, -1 do
        if theByte >= seperate[i] then return i end
    end
    return 1
end

2.4 獲取UTF-8字符串長度

function characters(utf8Str, aChineseCharBytes)
    aChineseCharBytes = aChineseCharBytes or 2
    local i = 1
    local characterSum = 0
    while (i <= #utf8Str) do      -- 編碼的關(guān)系
        local bytes4Character = Bytes4Character(string.byte(utf8Str, i))
        characterSum = characterSum + (bytes4Character > aChineseCharBytes and aChineseCharBytes or bytes4Character)
        i = i + bytes4Character
    end

    return characterSum
end

示例: UTF-8字符串:我們We

  1. 每一個中文算一個字符 characters("我們We", 1)

    示例1-代碼運行.png

  2. 游戲中希望把一個漢字當(dāng)做2個字節(jié)處理characters("我們We", 2)(因為1個漢字的寬度和2個字母相仿)

示例-代碼運行.png

附錄

標(biāo)準(zhǔn)ascii碼表.jpg

參考

  1. 阮一峰-字符編碼筆記:ASCII栏尚,Unicode 和 UTF-8
  2. 漢字對應(yīng)表
  3. lua匹配UTF-8中文漢字
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末起愈,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子译仗,更是在濱河造成了極大的恐慌抬虽,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纵菌,死亡現(xiàn)場離奇詭異阐污,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)咱圆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門笛辟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來功氨,“玉大人,你說我怎么就攤上這事隘膘∫晒剩” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵弯菊,是天一觀的道長纵势。 經(jīng)常有香客問我,道長管钳,這世上最難降的妖魔是什么钦铁? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮才漆,結(jié)果婚禮上牛曹,老公的妹妹穿的比我還像新娘。我一直安慰自己醇滥,他們只是感情好黎比,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鸳玩,像睡著了一般阅虫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上不跟,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天颓帝,我揣著相機(jī)與錄音,去河邊找鬼窝革。 笑死购城,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的虐译。 我是一名探鬼主播瘪板,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼漆诽!你這毒婦竟也來了篷帅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤拴泌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后惊橱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚪腐,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年税朴,在試婚紗的時候發(fā)現(xiàn)自己被綠了回季。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片家制。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖泡一,靈堂內(nèi)的尸體忽然破棺而出颤殴,到底是詐尸還是另有隱情,我是刑警寧澤鼻忠,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布涵但,位于F島的核電站,受9級特大地震影響帖蔓,放射性物質(zhì)發(fā)生泄漏矮瘟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一塑娇、第九天 我趴在偏房一處隱蔽的房頂上張望澈侠。 院中可真熱鬧,春花似錦埋酬、人聲如沸哨啃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拳球。三九已至,卻和暖如春耳标,著一層夾襖步出監(jiān)牢的瞬間醇坝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工次坡, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留呼猪,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓砸琅,卻偏偏與公主長得像宋距,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子症脂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容