参考博客: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编码的中英文混合字符串相关推荐

  1. php判断字符串里有英文,PHP针对中英文混合字符串长度判断及截取方法示例

    本文实例讲述了PHP针对中英文混合字符串长度判断及截取方法.分享给大家供大家参考,具体如下: /** * * 中英混合字符串长度判断 * @param unknown_type $str * @par ...

  2. php截取英语,php 截取中英文混合字符串的方法

    php 截取中应为字符串,就不必再用substr或者mb_substr //截取想这样的字符串 a李三 利用ASCII /** * * 中英混合的字符串截取 * @param unknown_type ...

  3. PHP截取中英文混合字符串

    <?php /*** 截取中英文混合字符串* @param $sourcestr 需要截取的字符串* @param $start 开始位置,字符位置,* @param $cutlength 结束 ...

  4. ASP如何计算中英文混合字符串长度和截取字符串

    用ASP做网站的时候经常会碰到要截取字符串的情况.ASP中的Len函数不管是中文字符,还是英文字符,统统按一个单位来计算,由于一个中文字符的宽度是一个英文字符宽度的两倍,在中英文混合的情况下字符串实际 ...

  5. C#实现 获取指定字节长度 中英文混合字符串 的方法

    平时在作数据库插入操作时,如果用 INSERT 语句向一个varchar型字段插入内容时,有时会因为插入的内容长度超出规定的长度而报错.尤其是插入中英文混合字符串时,SQL Server中一般中文要占 ...

  6. 中英文混合字符串长度的获取

    在项目中要处理中英文混合字符串的长度,中文按2个字符算,英文按1个字符算.以下是我处理的方法,不知道有没有更好的方法. private int GetGBLength(string strData) ...

  7. Javascript中得到中英文混合字符串的长度

    有同事在公司的OA上发了个贴子,介绍在javascript中如何得到中英文混合字符串的长度. 用的是正则表达式. var str = "坦克是tank的音译";var len = ...

  8. 计算中英文混合字符串长度

    - (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.//第一种方法NS ...

  9. php对中英文字符串进行截取,利用php怎么对中英文混合的字符串进行截取

    利用php怎么对中英文混合的字符串进行截取 发布时间:2021-01-04 15:31:24 来源:亿速云 阅读:103 作者:Leah 利用php怎么对中英文混合的字符串进行截取?很多新手对此不是很 ...

最新文章

  1. Echarts 动态获取数据进行图表的展示
  2. 结对编程项目作业-结对编项目设计文档
  3. 计算机组成原理中移码怎么算,计算机组成原理中移码是怎么回事?
  4. “快”和“持久”对弈:非旗舰处理器的破局之路
  5. hdu 1261 字串数
  6. CF 354E DFS
  7. XRD如何分析残余应力
  8. MQL5 中如何调用指标
  9. 一款优秀的IT资产管理系统-Snipe-IT 安装及用户手册中文版(二配置使用篇)
  10. 网站安全检测:推荐8款免费的 Web 安全测试工具
  11. 点燃创业引擎的天使投资
  12. top与with ties用法
  13. 五彩斑斓的颜色可预告心情
  14. 2020华为杯数学建模总结
  15. ERROR Executor: Exception in task 0.0 in stage 1.0 (TID 1) java.sql.BatchUpdateException: Duplicate
  16. 可行性、易用性性与用户体验的区别
  17. 小学计算机兴趣小组活动记计划,小学兴趣小组年度工作计划(通用5篇)
  18. 杰奇程序 php文件设置,杰奇模板修改说明.doc
  19. Python使用qbittoreent的webAPI实现自动下载种子
  20. 免疫算法(matlab)---求数的平方和

热门文章

  1. Service 层和 Dao 层有必要为每个类都加上接口吗?
  2. 从面试角度分析CopyOnWriteArrayList源码
  3. 经典面试题:ES如何做到亿级数据查询毫秒级返回?
  4. 面试官:消息队列这些我必问!
  5. 小说:白话幂等性设计
  6. 聊一聊如何优雅地向程序员提问题
  7. 做好数据可视化的技巧和原则!
  8. GNN 系列:Graph 基础知识介绍
  9. iPhone 13注定便宜不了,台积电已提前背锅
  10. Colab不好用,有人花两年开发了一个新notebook,支持实时协作还更快