Lua中获取字符串长度整理

Lua 中,获取字符串长度我们一般使用 #str(不建议使用 string.len(str) )!

local str = "abc"
local len = #str
print(len)  -- 3

str = "你们好"
len = #str
print(len)  -- 9

这里就出现了一个问题:为啥字符串 abc 的长度为 3,而字符串 你们好 的长度却是 9 呢?难道是哪里出问题了?当然不是!

其实这是字符编码导致的,在使用 UTF-8 字符编码的情况下,一个中文字符一般占 3 个字节,所以 3 个中文字符自然就是 9 个字节咯!

那么问题来了,现在我需要不管是中文字符还是其他字符,长度都为 1 该咋整呢?

这里记录两种方案:

方案一

-- 获取字符串的长度(任何单个字符长度都为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

归根结底其实就是对 UTF-8 字符编码进行处理!

参考:

关于字符编码的八个点

在Lua中计算含中文的字符串的长度

  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fightsyj

您的鼓励将是我分享的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值