unicode(utf16)和utf8编码的字符串互转,纯lua实现

适用条件:unicode编码只能是utf-16,不支持utf-32

使用方法:字符串 “你好ab7a天天” 对应的unicode编码是 \u4f60\u597d\u0061\u0062\u0037\u0061\u5929\u5929 或者 \u4f60\u597dab7a\u5929\u5929(某些三方平台会返回这种编码格式,即字母和数字不进行编码);测试代码:
第一步: uniStr="\u4f60\u597d\u0061\u0062\u0037\u0061\u5929\u5929"或者uniStr="\u4f60\u597dab7a\u5929\u5929"(假设这个就是服务器返回来的unicode数据,注意不能在lua中直接这样赋值,因为\是转义字符,lua会报错的,我这里是为了方便讲解,反正服务器传过来的unicode数据你就直接赋给uniStr)
第二步: uniStr = string.gsub(uniStr,"\u","\\u") --因为\是转义字符,所以要这样处理下,处理之后uniStr的值就会变为"\u4f60\u597d\u0061\u0062\u0037\u0061\u5929\u5929"或者"\u4f60\u597dab7a\u5929\u5929"

第三步:local utf8Str=unicode_to_utf8(uniStr) --这一步就是转换操作了,返回值就是 “你好ab7a天天”

使用方法很简单的,还有我这个支持多语言,比如这个"\u3053\u3093\u306b\u3061\u306f"是日文的unicode编码,转换成utf8就是 こんにちは

上源码:
local bit = require(“bit”)

local function unicode_to_utf8(convertStr)

if type(convertStr)~="string" then

return convertStr
end

local resultStr=""
local i=1
while true do

    local num1=string.byte(convertStr,i)
    local unicode

    if num1~=nil and string.sub(convertStr,i,i+1)=="\\u" then
        unicode=tonumber("0x"..string.sub(convertStr,i+2,i+5))
        i=i+6

elseif num1~=nil then
unicode=num1
i=i+1
else
break
end

    print(unicode)

    if unicode <= 0x007f then


        resultStr=resultStr..string.char(bit.band(unicode,0x7f))


    elseif unicode >= 0x0080 and unicode <= 0x07ff then

        resultStr=resultStr..string.char(bit.bor(0xc0,bit.band(bit.rshift(unicode,6),0x1f)))

        resultStr=resultStr..string.char(bit.bor(0x80,bit.band(unicode,0x3f)))


    elseif unicode >= 0x0800 and unicode <= 0xffff then


        resultStr=resultStr..string.char(bit.bor(0xe0,bit.band(bit.rshift(unicode,12),0x0f)))

        resultStr=resultStr..string.char(bit.bor(0x80,bit.band(bit.rshift(unicode,6),0x3f)))

        resultStr=resultStr..string.char(bit.bor(0x80,bit.band(unicode,0x3f)))


    end

end

resultStr=resultStr…’\0’

print(resultStr)

return resultStr

end

local function utf8_to_unicode(convertStr)

if type(convertStr)~="string" then

return convertStr
end

local resultStr=""
local i=1
local num1=string.byte(convertStr,i)

while num1~=nil do

    print(num1)

local tempVar1,tempVar2

    if num1 >= 0x00 and num1 <= 0x7f then


        tempVar1=num1


        tempVar2=0


    elseif bit.band(num1,0xe0)== 0xc0 then


        local t1 = 0
        local t2 = 0

        t1 = bit.band(num1,bit.rshift(0xff,3))
        i=i+1
        num1=string.byte(convertStr,i)

        t2 = bit.band(num1,bit.rshift(0xff,2))


        tempVar1=bit.bor(t2,bit.lshift(bit.band(t1,bit.rshift(0xff,6)),6))

        tempVar2=bit.rshift(t1,2)


    elseif bit.band(num1,0xf0)== 0xe0 then


        local t1 = 0
        local t2 = 0
        local t3 = 0

        t1 = bit.band(num1,bit.rshift(0xff,3))
        i=i+1
        num1=string.byte(convertStr,i)
        t2 = bit.band(num1,bit.rshift(0xff,2))
        i=i+1
        num1=string.byte(convertStr,i)
        t3 = bit.band(num1,bit.rshift(0xff,2))

        tempVar1=bit.bor(bit.lshift(bit.band(t2,bit.rshift(0xff,6)),6),t3)
        tempVar2=bit.bor(bit.lshift(t1,4),bit.rshift(t2,2))

    end

resultStr=resultStr…string.format("\u%02x%02x",tempVar2,tempVar1)
print(resultStr)

    i=i+1
    num1=string.byte(convertStr,i)
end

print(resultStr)

return resultStr

end

如果还有什么不明白的,请下载附件,我提供了完整的测试例子。
用cocos2d-x 3.2 、cocos code ide1.2.0创建一个lua工程,然后替换掉src下的main.lua文件,就可以了,main.lua里面写得非常清楚,请仔细看!!!

main.lua.zip (3 KB)

顶起。。。先收藏以后用。:2:

亲测可用!谢谢分享!

:2: :2: :2: :2: :2: :2: :2: :2: :2:

看的人好少啊,:14::14::14::14::14::14:

这个不错,可以脱离操作系统的api了。

c++11自带转换库,写好暴露给lua用就可以了