对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
end
local code = string.byte(char)
if code < then
return
elseif code <= then
return
elseif code <= then
return
elseif code <= then
return
else
-- 讲道理不会走到这里^_^
return
end
end function StringHelper.Sub(str, startIndex, endIndex)
local tempStr = str
local byteStart = -- string.sub截取的开始位置
local byteEnd = - -- string.sub截取的结束位置
local index = -- 字符记数
local bytes = -- 字符的字节记数 startIndex = math.max(startIndex, )
endIndex = endIndex or -
while string.len(tempStr) > do
if index == startIndex - then
byteStart = bytes+;
elseif index == endIndex then
byteEnd = bytes;
break;
end
bytes = bytes + StringHelper.GetBytes(tempStr)
tempStr = string.sub(str, bytes+) index = index +
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, , ))
print(StringHelper.Sub(str, ))
print(StringHelper.Sub(str, , ))

测试结果:

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

  1. 标准 DateTime 格式字符串

    标准 DateTime 格式字符串 MSDN 标准 DateTime 格式字符串包含一个标准 DateTime 格式说明符字符,该字符表示自定义 DateTime 格式字符串.格式字符串最终定义由格式 ...

  2. java中驼峰与下横线格式字符串互转算法

    public static final char UNDERLINE = '_'; /** * 驼峰格式字符串转换为下划线格式字符串 * * @param param * @return */ pub ...

  3. web 前端 常见操作 将时间戳转成日期格式 字符串截取 使用mui制作选项卡

    1.将时间戳转成日期格式: //第一种 function getLocalTime(nS) { return new Date(parseInt(nS) * 1000).toLocaleString( ...

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

    1. cut [选项] 文件名 -f  列号 #提取第几列(分隔符默认为\t) -d  分隔符 #指定分隔符 例如:cut -f 2 a.txt #截取文件a.txt内容的第二列(列号从1开始) cu ...

  5. lr_save_var字符串截取总结

    函数作用: 将一个变化长度的字符串保存到parameter中. 用法实例: 此处讲解函数: Action() {     web_save_timestamp_param("tStamp&q ...

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

    感觉上MySQL的字符串函数截取字符,比用程序截取(如PHP或JAVA)来得强大,所以在这里做一个记录,希望对大家有用. 函数: 1.从左开始截取字符串 left(str, length) 说明:le ...

  7. shell字符串操作之cut---实现字符串截取

    shell中(字符串截取) cut是以每一行为一个处理对象的,这种机制和sed是一样的.(关于sed的入门文章将在近期发布) 2 cut一般以什么为依据呢? 也就是说,我怎么告诉cut我想定位到的剪切 ...

  8. 关于Java和JavaScript对字符串截取处理的总结

    在JavaWeb开发中,经常需要对字符串进行处理,包括Java语言和JS语言,总是容易弄混淆,这里简单对比一下两种语言对于字符串截取方法. 一.先看Java public class StringDe ...

  9. thinkPHP内置字符串截取msubstr函数用法详解

    作者:陈达辉 字体:[增加 减小] 类型:转载 时间:2016-11-15 我要评论 这篇文章主要介绍了thinkPHP内置字符串截取函数用法,结合实例形式分析了thinkPHP内置的字符串截取函数功 ...

  10. MySQL 字符串截取SUBSTRING()函数

    MySQL 字符串截取相关函数: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例: select left(content,200) as ab ...

随机推荐

  1. 关于使用express作为spa应用服务的问题

    前端工程师应该知道,spa是基于前端路由的单页面应用,如果服务端不做相应的配置,会经常出现404的问题. 一般的做法是默认返回应用的首页. express // 安装相关依赖 npm install ...

  2. solr系列之solr-5.5.5 window单机版jdk-1.7 tomcat8安装

    一.Solr5.5.5.Tomcat8-x64.jdk-1.7-64单机部署 1.准备安装包,下载solr和tomcat的安装,直接解压即可(上篇一提供solr的下载路径) 2.在Solr5之前都还存 ...

  3. springboot 配置跨越访问

    import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.H ...

  4. JS基础_数组的方法

    常用的方法 1.push:向数组的末尾添加一个或更多元素,并返回新的长度. 将要添加的元素作为方法的参数传递,这些元素将会自动添加到数组的末尾 var a=[1,2,3]; var r = a.pus ...

  5. python之ActionChains方法列表

    使用方法: 方法列表: click(on_element=None) ——单击鼠标左键 click_and_hold(on_element=None) ——点击鼠标左键,不松开 context_cli ...

  6. 中间件 | kafka简介、使用场景、设计原理、主要配置及集群搭建

    开源Java学习 公众号 一.入门 1.简介 Kafka is a distributed,partitioned,replicated commit logservice.它提供了类似于JMS的特性 ...

  7. 发布js插件zhen-chek(用来检测数据类型)到npm上

    今天想到js本身是弱类型,在实际项目中很多时候需要数据类型检测.于是打算做一个判断数据类型的js插件,发布到npm上面. 基本思路: 1,输入参数,便返回数据类型,所有数据类型如下 '[object ...

  8. instanceof 实现

    A instanceof B // 实现 instanceof function instance(a, b) { const proto = a.__proto__; // eslint-disab ...

  9. 你真的理解Java中的try/catch/finally吗?

    看几个例子,回顾一下执行顺序 例子1 无异常,finally中的return会导致提前返回 public static String test() {    try {        System.o ...

  10. piggy back是什么意思?

    遇到这么一句话. // Connect the Socket.IO framework up to the web server to piggy back on its connection // ...