阅读 111

Lua计算字符串长度

前言

众所周知,lua可以使用#获取字符串或者table的长度,例如:

local temp = "23dd"
print("长度 = ",#temp) ---长度 = 4

local temp2 = "大家"
print("长度 = ",#temp2) --- 长度 = 6
复制代码

为什么会有这种情况呢? 因为在UTF-8的编码模式下,当字符在ASCII中可以被表示时,就是用1个字节存储,但汉字使用3个字节存储。所以对于含有非ASCII字符的字符串,#计算出的长度可能不是我们想要的。

讨论

所幸lua实现很强大,在使用UTF-8编码方式时,可以使用字符序列(1-4个字节)表示其他编码方式的单个字符。例如可以用单个字符表示所有的ASCII范围内的字符,所以: 若使用一个字节表示其他编码方式的单个字符,其范围为[0,127]; 使用两个字节表示,其第一个字节范围为[194,223]; 使用三个字节表示,其第一个字节范围为[224,239]; 使用四个字节表示,其第一个字节范围为[240,247];

实现

所以需要自己实现一种无论汉字,ASCII字符所占长度都为1的字符串计算方法。

function getLength(str)
    if not str or #str <= 0 then
        return 0
    end

    local length = 0
    local index = 1

    while true do
        local curByteNum = string.byte(str,index)

        if curByteNum >= 0 and curByteNum <= 127 then
            index = index + 1
        elseif curByteNum >= 194 and curByteNum <= 223 then
            index = index + 2
        elseif curByteNum >= 224 and curByteNum <= 239 then
            index = index + 3
        elseif curByteNum >= 240 and curByteNum < 247 then
            index = index + 4
        end
        length = length + 1
        if index > #str then
            break
        end
    end
    return length
end
复制代码
print(getLength("稍等双方围绕服务dsddd2232"))  --17
print(getLength("we")) --2
print(getLength("试试")) --2
复制代码