UTF8字符串在lua的截取和字数统计【转载】
2016-03-16 11:22
344 查看
转载自:GitHub:pangliang/pangliang.github.com
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
2. 字符长度有规律
UTF-8字符规律
字符串的首个byte表示了该utf8字符的长度
0xxxxxxx - 1 byte
110yxxxx - 192, 2 byte
1110yyyy - 225, 3 byte
11110zzz - 240, 4 byte
需求
按字面个数来截取函数(字符串, 开始位置, 截取长度) 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
正确算法
-- -- lua -- 判断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()
相关文章推荐
- <转> Lua使用心得(2)
- (转) Lua使用心得一 LUA和VC整合
- Failed to notify ProjectEvaluationListener.afterEvaluate(), but primary configuration failure takes
- lua相关
- lua 远程调试 【zeroBrane 使用mobdebug】(good转)
- ZeroBrane Studio远程调试Lua程序(转)
- Lua中的metatable详解
- 使用lua实现几个小算法
- ngx_lua实现重启php
- 156.Evaluate the following SQL statement:
- uLua学习笔
- Lua中的string库(字符串函数库)总结
- LUA string库详解
- Lua -- select用法
- lua socket
- 有关Lua脚本语言应用
- Sublime -- 配置lua环境
- Lua面向对象程序设计
- lua Date和Time
- lua-协成