在 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 字符编码进行处理!
参考: