Lua 截取字符串(截取utf-8格式字符串)

对utf-8完全没概念的可以看看我上一篇随笔:

另外,还要知道string.sub 和 string.byte 的用法。

先上完整代码:

local  StringHelper = {}

--[[
utf-8编码规则
单字节 - 0起头
   1字节  0xxxxxxx   0 - 127
多字节 - 第一个字节n个1加1个0起头
   2 字节 110xxxxx   192 - 223
   3 字节 1110xxxx   224 - 239
   4 字节 11110xxx   240 - 247
可能有1-4个字节
--]]
function StringHelper.GetBytes(char)
   if not char then
      return 0
   end
   local code = string.byte(char)
   if code < 127 then
      return 1
   elseif code <= 223 then
      return 2
   elseif code <= 239 then
      return 3
   elseif code <= 247 then
      return 4
   else
      -- 讲道理不会走到这里^_^
      return 0
   end
end

function StringHelper.Sub(str, startIndex, endIndex)
   local tempStr = str
   local byteStart = 1 -- string.sub截取的开始位置
   local byteEnd = -1 -- string.sub截取的结束位置
   local index = 0  -- 字符记数
   local bytes = 0  -- 字符的字节记数

   startIndex = math.max(startIndex, 1)
   endIndex = endIndex or -1
   while string.len(tempStr) > 0 do
      if index == startIndex - 1 then
         byteStart = bytes+1;
      elseif index == endIndex then
         byteEnd = bytes;
         break;
      end
      bytes = bytes + StringHelper.GetBytes(tempStr)
      tempStr = string.sub(str, bytes+1)

      index = index + 1
   end
   return string.sub(str, byteStart, byteEnd)
end

基本思路:

之所以要自己写一个截取函数,是因为lua的库函数string.sub实际是字节的截取函数。

uft-8编码格式中,大部分中文是3个字节表示的,数字和字母等是一个字节的,还有某些国家的语言是2字节的,直接用string.sub就可能截出乱码来,因为不确定要截多少个字节。

所以,

定义一个GetBytes函数,获取字符的字节数(根据首个字节的高位标记,判断是几字节的字符)

然后不断后移,记录字节数和字符数。

如上图,假设要取字符3-4,那么应该从第3个字符的第一个字节取到第4个字最后一个字节

即:

当前字符数为截取的起始字符(startIndex)前一个位置时,说明从下一个字节开始截取字符串   即 index == startIndex - 1 时 byteStart = bytes+1

当前字符数为截取的终止字符(endIndex)时,说明要截取的字符串到此为止   即 index == endIndex 时 byteEnd = bytes

用 string.sub(str, byteStart, byteEnd) 就能截取byteStart 到 byteEnd 的字节

测试代码:

str = "中1文*a字符串勉強します";
print(StringHelper.Sub(str, 3, 4))
print(StringHelper.Sub(str, 1, 4))
print(StringHelper.Sub(str, 8))
print(StringHelper.Sub(str, 2, 12))

测试结果:

原文地址:https://www.cnblogs.com/yougoo/p/11960801.html

时间: 2024-11-07 09:58:56

Lua 截取字符串(截取utf-8格式字符串)的相关文章

标准 DateTime 格式字符串

标准 DateTime 格式字符串 MSDN 标准 DateTime 格式字符串包含一个标准 DateTime 格式说明符字符,该字符表示自定义 DateTime 格式字符串.格式字符串最终定义由格式化操作产生的 DateTime 对象的文本表示形式.请注意,任何包含一个以上字母字符(包括空白)的 DateTime 格式字符串都被解释为自定义 DateTime 格式字符串. 标准 DateTime 格式说明符 下表描述了标准 DateTime 格式说明符.有关各格式说明符所产生输出的示例,请参见

Linux下实现字符串截取方法总结

Linux下实现字符串截取,大体上可以分为两种,使用命令实现截取,使用工具实现截取.具体截取方式如下: a.#截取,可以实现删除左边字符,保留右边字符 从左边第一个</>开始,删除</>及之前的所有字符 str=http://www.baidu.com/index.html echo ${str#*/}        # right first / 输出:      /www.baidu.com/index.html b.##截取,可以实现删除左边字符,保留右边字符 从最右边的&l

Linux字符串截取和处理命令 cut、printf、awk、sed、sort、wc

1. cut [选项] 文件名 -f  列号 #提取第几列(分隔符默认为\t) -d  分隔符 #指定分隔符 例如:cut -f 2 a.txt #截取文件a.txt内容的第二列(列号从1开始) cut -f 2,4 a.txt #截取文件a.txt内容的第二列和第四列 cut -d  ":"  -f 1,3 /etc/passwd #截取文件passwd文件的第1列和第三列,以:分割取其中的第一列和第三列 2. printf '输出类型 输出格式'  输出内容 输出类型: %ns 输

【转】BAT批处理中的字符串处理详解(字符串截取)

下面对这些功能一一进行讲解. 1.截取字符串 截取字符串可以说是字符串处理功能中最常用的一个子功能了,能够实现截取字符串中的特定位置的一个或多个字符.举例说明其基本功能: @echo off set ifo=abcdefghijklmnopqrstuvwxyz0123456789 echo 原字符串(第二行为各字符的序号): echo %ifo% echo 123456789012345678901234567890123456 echo 截取前5个字符: echo %ifo:~0,5% ech

探索字符串截取命令之---sed命令

sed命令其实不能算作是字符串截取命令,准确的说应该叫做替换命令,因为它在日常工作中的用处主要是用来替换的. sed [选项] '[动作]' 文件名 选项: -n 只有加了-n 后面的动作才能生效 -e 多条命令的编辑 -i 用sed直接修改文件内容 动作: a 追加 c 行替换 i 插入 d 删除指定的行 p 打印 s 字符串替换 格式:行范围s/旧字符串/新字符串/g 咱们一个一个来解密: ① -n格式: sed -n '2p' test 看到了吗?不加-n是不行的 ② c和s的区别 如果加

一个关于字符串截取输出的例子

要求:给定字符串"1234"或者"12345",输出以下序列. output-> "1234","123","234","12","23","34","1","2","3","4"  "12345","1234","

Mysql字符串截取函数SUBSTRING和ASCII()函数

函数SUBSTRING: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例:select left(content,200) as abstract from my_content_t 2.从右开始截取字符串 right(str, length) 说明:right(被截取字段,截取长度) 例:select right(content,200) as abstract from my_content_t 3.截取字符串 substring(st

Mysql字符串截取函数SUBSTRING的用法说明

感觉上MySQL的字符串函数截取字符,比用程序截取(如PHP或JAVA)来得强大,所以在这里做一个记录,希望对大家有用. 函数: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例:select left(content,200) as abstract from my_content_t 2.从右开始截取字符串 right(str, length) 说明:right(被截取字段,截取长度) 例:select right(content,200

求助:关于字符串截取的问题

类似于:jdbc:mysql://localhost:3306/bill?characterEncoding=utf-8这种格式字符串,想分别将mysql .  localhost.3306.bill信息从该字符串中提取出来,用该如何提取. 希望大家给点建议和思路 本问题已解决: 本人思路有两种,第一种思路 //第一种方法 /**  *   * @param tags 所要处理的字符  * @param str  所要处理的字符串  * @return  * @throws Exception

Day04 字符串截取&amp;字符串初值&amp;数组&amp;字符串替换

一.字符串截取 ":"代表截取 1.1 ${var:起始位置:长度} 起始位置从0开始(为0可以省略)x=13918581996echo ${x::5}#只取前5位数字13918 1.2 expr substr "$var" 起始位置 长度 起始位置从1开始x=13918581996expr substr "$x" 1 513918 1.3 cut -b 起始位置-结束位置 按照顺序截取,起始位置从1开始echo $x|cut -b 1-5139