lua截取字符,以及取字符个数(⾮字符串长度)
需求
按字⾯个数来截取
函数(字符串, 开始位置, 截取长度)
utf8sub("你好1世界哈哈",2,5) = 好1世界哈
utf8sub("1你好1世界哈哈",2,5) = 你好1世界
utf8sub("你好世界1哈哈",1,5) = 你好世界1
utf8sub("12345678",3,5)  = 34567
utf8sub("øpø你好pix",2,5) = pø你好p
错误⽅法
⽹上了⼀些算法, 都不太正确; 要么就是乱码, 要么就是只考虑了4 byte 中⽂的情况, 不够全⾯
1. string.sub(s,1,截取长度*4)
⽹上很多直接使⽤”""string.sub(s,1,截取长度*4)“是肯定不对的, 因为如果中英⽂混合的字符串, 例如你好1世界的字符长度分别是4,4,1,4,4, 如果截取4个字, 4*4=4+4+1+4+3, 那世界的界字将会被取前3个byte, 就会出现乱码
2. if byte>128 then index = index + 4
问题关键
1. utf8字符是变长字符
2. 字符长度有规律
UTF-8字符规律
字符串的⾸个byte表⽰了该utf8字符的长度
0xxxxxxx - 1 byte
110yxxxx - 192, 2 byte
1110yyyy - 225, 3 byte
11110zzz - 240, 4 byte
各种正确算法
-- 判断utf8字符byte长度
-- 0xxxxxxx - 1 byte
-- 110yxxxx - 192, 2 byte
-- 1110yyyy - 225, 3 byte
-- 11110zzz - 240, 4 byte
local function chsize(char)
if not char then
print("not char")
return 0
elseif char > 240 then
return 4
elseif char > 225 then
return 3
elseif char > 192 then
return 2
else
return 1
end
end
-
- 计算utf8字符串字符数, 各种字符都按⼀个字符计算
-- 例如utf8len("1你好") => 3
function utf8len(str)
local len = 0
local currentIndex = 1
while currentIndex <= #str do
local char = string.byte(str, currentIndex)
currentIndex = currentIndex + chsize(char)
len = len +1
end
return len
end
-- 截取utf8 字符串
-- str:            要截取的字符串
字符串长度不同怎样取
-- startChar:    开始字符下标,从1开始
-- numChars:    要截取的字符长度
function utf8sub(str, startChar, numChars)
local startIndex = 1
while startChar > 1 do
local char = string.byte(str, startIndex)
startIndex = startIndex + chsize(char)
startChar = startChar - 1
end
local currentIndex = startIndex
while numChars > 0 and currentIndex <= #str do
local char = string.byte(str, currentIndex)
currentIndex = currentIndex + chsize(char)
numChars = numChars -1
end
return str:sub(startIndex, currentIndex - 1)
end
-- ⾃测
function test()
-
- test utf8len
assert(utf8len("你好1世界哈哈") == 7)
assert(utf8len("你好世界1哈哈 ") == 8)
assert(utf8len(" 你好世界1哈哈") == 9)
assert(utf8len("12345678") == 8)
assert(utf8len("øpø你好pix") == 8)
-- test utf8sub
assert(utf8sub("你好1世界哈哈",2,5) == "好1世界哈")    assert(utf8sub("1你好1世界哈哈",2,5) == "你好1世界")    assert(utf8sub(" 你好1世界哈哈",2,6) == "你好1世界 ")    assert(utf8sub("你好世界1哈哈",1,5) == "你好世界1")    assert(utf8sub("12345678",3,5) == "34567")
assert(utf8sub("øpø你好pix",2,5) == "pø你好p")
print("all test succ")
end
test()

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。