前言
众所周知,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