Lua截取utf-8编码的中英文混合字符串
参考博客:UTF8字符串在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是对unicode字符集的编码方案。因此其变长编码方式为:
一字节:0*******
两字节:110*****,10******
三字节:1110****,10******,10******
四字节:11110***,10******,10******,10******
五字节:111110**,10******,10******,10******,10******
六字节:1111110*,10******,10******,10******,10******,10******
因此,拿到字节串后,想判断UTF8字符的byte长度,按照上文的规律,只需要获取该字符的首个Byte,根据其值就可以判断出该字符由几个Byte表示。
其代码如下:
local funciton charsize(ch)if not ch then return 0elseif ch >=252 then return 6elseif ch >= 248 and ch < 252 then return 5elseif ch >= 240 and ch < 248 then return 4elseif ch >= 224 and ch < 240 then return 3elseif ch >= 192 and ch < 224 then return 2elseif ch < 192 then return 1end end
-- 计算utf8字符串字符数, 各种字符都按一个字符计算 -- 例如utf8len("1你好") => 3 function utf8len(str)local len = 0local aNum = 0 --字母个数local hNum = 0 --汉字个数local currentIndex = 1while currentIndex <= #str dolocal char = string.byte(str, currentIndex)local cs = charsize(char)currentIndex = currentIndex + cslen = len +1if cs == 1 then aNum = aNum + 1elseif cs >= 2 then hNum = hNum + 1endendreturn len, aNum, hNum end
-- 截取utf8 字符串 -- str: 要截取的字符串 -- startChar: 开始字符下标,从1开始 -- numChars: 要截取的字符长度 function utf8sub(str, startChar, numChars)local startIndex = 1while startChar > 1 dolocal char = string.byte(str, startIndex)startIndex = startIndex + chsize(char)startChar = startChar - 1endlocal currentIndex = startIndexwhile numChars > 0 and currentIndex <= #str dolocal char = string.byte(str, currentIndex)currentIndex = currentIndex + chsize(char)numChars = numChars -1endreturn str:sub(startIndex, currentIndex - 1) end-- 自测 function test()-- test utf8lenassert(utf8len("你好1世界哈哈") == 7)assert(utf8len("你好世界1哈哈 ") == 8)assert(utf8len(" 你好世 界1哈哈") == 9)assert(utf8len("12345678") == 8)assert(utf8len("øpø你好pix") == 8)-- test utf8subassert(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") endtest()
Lua截取utf-8编码的中英文混合字符串相关推荐
- php判断字符串里有英文,PHP针对中英文混合字符串长度判断及截取方法示例
本文实例讲述了PHP针对中英文混合字符串长度判断及截取方法.分享给大家供大家参考,具体如下: /** * * 中英混合字符串长度判断 * @param unknown_type $str * @par ...
- php截取英语,php 截取中英文混合字符串的方法
php 截取中应为字符串,就不必再用substr或者mb_substr //截取想这样的字符串 a李三 利用ASCII /** * * 中英混合的字符串截取 * @param unknown_type ...
- PHP截取中英文混合字符串
<?php /*** 截取中英文混合字符串* @param $sourcestr 需要截取的字符串* @param $start 开始位置,字符位置,* @param $cutlength 结束 ...
- ASP如何计算中英文混合字符串长度和截取字符串
用ASP做网站的时候经常会碰到要截取字符串的情况.ASP中的Len函数不管是中文字符,还是英文字符,统统按一个单位来计算,由于一个中文字符的宽度是一个英文字符宽度的两倍,在中英文混合的情况下字符串实际 ...
- C#实现 获取指定字节长度 中英文混合字符串 的方法
平时在作数据库插入操作时,如果用 INSERT 语句向一个varchar型字段插入内容时,有时会因为插入的内容长度超出规定的长度而报错.尤其是插入中英文混合字符串时,SQL Server中一般中文要占 ...
- 中英文混合字符串长度的获取
在项目中要处理中英文混合字符串的长度,中文按2个字符算,英文按1个字符算.以下是我处理的方法,不知道有没有更好的方法. private int GetGBLength(string strData) ...
- Javascript中得到中英文混合字符串的长度
有同事在公司的OA上发了个贴子,介绍在javascript中如何得到中英文混合字符串的长度. 用的是正则表达式. var str = "坦克是tank的音译";var len = ...
- 计算中英文混合字符串长度
- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//第一种方法NS ...
- php对中英文字符串进行截取,利用php怎么对中英文混合的字符串进行截取
利用php怎么对中英文混合的字符串进行截取 发布时间:2021-01-04 15:31:24 来源:亿速云 阅读:103 作者:Leah 利用php怎么对中英文混合的字符串进行截取?很多新手对此不是很 ...
最新文章
- Echarts 动态获取数据进行图表的展示
- 结对编程项目作业-结对编项目设计文档
- 计算机组成原理中移码怎么算,计算机组成原理中移码是怎么回事?
- “快”和“持久”对弈:非旗舰处理器的破局之路
- hdu 1261 字串数
- CF 354E DFS
- XRD如何分析残余应力
- MQL5 中如何调用指标
- 一款优秀的IT资产管理系统-Snipe-IT 安装及用户手册中文版(二配置使用篇)
- 网站安全检测:推荐8款免费的 Web 安全测试工具
- 点燃创业引擎的天使投资
- top与with ties用法
- 五彩斑斓的颜色可预告心情
- 2020华为杯数学建模总结
- ERROR Executor: Exception in task 0.0 in stage 1.0 (TID 1) java.sql.BatchUpdateException: Duplicate
- 可行性、易用性性与用户体验的区别
- 小学计算机兴趣小组活动记计划,小学兴趣小组年度工作计划(通用5篇)
- 杰奇程序 php文件设置,杰奇模板修改说明.doc
- Python使用qbittoreent的webAPI实现自动下载种子
- 免疫算法(matlab)---求数的平方和