Lua中获取字符串长度

偶然的情况下,需要用Lua代码获取字符串的长度,结果发现结果和自己想象的不一样,一个汉字算两个英文字符的时代已经快过去了,一个中文字符打印出来的长度为3,引起了我的好奇,查找资料了解了具体原因

不同的编码格式占字节数是不同的,UTF-8编码下一个中文所占字节也是不确定的,通常是3个字符,可能是2个、4个字节;

出于效率考虑,于是又弄了一个UTF-16,不严谨地来说它等价于Unicode原生编码,它统一采用双字节表示一个字符

下面是Unicode和UTF-8转换的规则 

 

 1 Unicode 
 2    
 3 UTF-8 
 4    
 5 0000 - 007F 
 6    
 7 0xxxxxxx 
 8    
 9 0080 - 07FF 
10    
11 110xxxxx 10xxxxxx 
12    
13 0800 - FFFF 
14    
15 1110xxxx 10xxxxxx 10xxxxxx

例如"汉"字的Unicode编码是6C49

6C49在0800-FFFF之间,所以要用3字节模板:1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是:0110 1100 0100 1001,将这个比特流按三字节模板的分段方法分为0110 110001 001001,依次代替模板中的x,得到:

1110-0110 10-110001 10-001001,即E6 B1 89,这就是其UTF8的编码

GBK、GB2312收编的汉字占2个字节,严格地用iso8859-1无法表示汉字,只能转为问号

下面是Lua获取字符串长度的方法:

方案一:

-- 获取字符串的长度(任何单个字符长度都为1)
function getStringLength(inputstr)
    if not inputstr or type(inputstr) ~= "string" or #inputstr <= 0 then
        return nil
    end
    local length = 0  -- 字符的个数
    local i = 1
    while true do
        local curByte = string.byte(inputstr, i)
        local byteCount = 1
        if curByte > 239 then
            byteCount = 4  -- 4字节字符
        elseif curByte > 223 then
            byteCount = 3  -- 汉字
        elseif curByte > 128 then
            byteCount = 2  -- 双字节字符
        else
            byteCount = 1  -- 单字节字符
        end
        -- local char = string.sub(inputstr, i, i + byteCount - 1)
        -- print(char)  -- 打印单个字符
        i = i + byteCount
        length = length + 1
        if i > #inputstr then
            break
        end
    end
    return length
end
 
local str = "I think,故我在!"
local len = getStringLength(str)
print(len)  -- 12

方案二:

-- 计算 UTF8 字符串的长度,每一个中文算一个字符
function utf8len(input)
    local len  = string.len(input)
    local left = len
    local cnt  = 0
    local arr  = {0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}
    while left ~= 0 do
        local tmp = string.byte(input, left)
        local i   = #arr
        while arr[i] do
            if tmp >= arr[i] then
                left = left - i
                break
            end
            i = i - 1
        end
        cnt = cnt + 1
    end
    return cnt
end
 
local str = "I think,故我在!"
local len = utf8len(str)
print(len)  -- 12

 

一个汉字占几个字节,详解与原理:

https://www.cnblogs.com/lslk89/p/6898526.html

https://blog.csdn.net/wowotuo/article/details/60333350

 

Lua中获取字符串长度:https://blog.csdn.net/fightsyj/article/details/83589997

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值