Lua 截取字符串(截取utf-8格式字符串)
对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格式字符串)的更多相关文章
- 标准 DateTime 格式字符串
标准 DateTime 格式字符串 MSDN 标准 DateTime 格式字符串包含一个标准 DateTime 格式说明符字符,该字符表示自定义 DateTime 格式字符串.格式字符串最终定义由格式 ...
- java中驼峰与下横线格式字符串互转算法
public static final char UNDERLINE = '_'; /** * 驼峰格式字符串转换为下划线格式字符串 * * @param param * @return */ pub ...
- web 前端 常见操作 将时间戳转成日期格式 字符串截取 使用mui制作选项卡
1.将时间戳转成日期格式: //第一种 function getLocalTime(nS) { return new Date(parseInt(nS) * 1000).toLocaleString( ...
- Linux字符串截取和处理命令 cut、printf、awk、sed、sort、wc
1. cut [选项] 文件名 -f 列号 #提取第几列(分隔符默认为\t) -d 分隔符 #指定分隔符 例如:cut -f 2 a.txt #截取文件a.txt内容的第二列(列号从1开始) cu ...
- lr_save_var字符串截取总结
函数作用: 将一个变化长度的字符串保存到parameter中. 用法实例: 此处讲解函数: Action() { web_save_timestamp_param("tStamp&q ...
- Mysql字符串截取函数SUBSTRING的用法说明
感觉上MySQL的字符串函数截取字符,比用程序截取(如PHP或JAVA)来得强大,所以在这里做一个记录,希望对大家有用. 函数: 1.从左开始截取字符串 left(str, length) 说明:le ...
- shell字符串操作之cut---实现字符串截取
shell中(字符串截取) cut是以每一行为一个处理对象的,这种机制和sed是一样的.(关于sed的入门文章将在近期发布) 2 cut一般以什么为依据呢? 也就是说,我怎么告诉cut我想定位到的剪切 ...
- 关于Java和JavaScript对字符串截取处理的总结
在JavaWeb开发中,经常需要对字符串进行处理,包括Java语言和JS语言,总是容易弄混淆,这里简单对比一下两种语言对于字符串截取方法. 一.先看Java public class StringDe ...
- thinkPHP内置字符串截取msubstr函数用法详解
作者:陈达辉 字体:[增加 减小] 类型:转载 时间:2016-11-15 我要评论 这篇文章主要介绍了thinkPHP内置字符串截取函数用法,结合实例形式分析了thinkPHP内置的字符串截取函数功 ...
- MySQL 字符串截取SUBSTRING()函数
MySQL 字符串截取相关函数: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例: select left(content,200) as ab ...
随机推荐
- 文本处理工具sed
处理文本的工具sed 行编辑器 ,默认自带循环. sed是一种流编辑器,它一次处理一行内容. 功能:主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等 sed工具 用法: sed ...
- HTTP之缓存技术
1. 缓存简介 缓存是位于服务器和客户端的中间单元,主要根据用户代理发送过来的请求,向服务器请求相关内容后提供给用户,并保存内容副本,例如 HTML 页面.图片.文本文件或者流媒体文件.然后,当下一个 ...
- NProgress的使用 及 路由 token 定向的使用
主要配合路由生命周期使用 实现一个进度条的效果 使用方法: 1. 下载:npm install --save nprogress 使用:NProgress.start(); 开始 NProgress ...
- nodejs服务端实现post请求
博客之前写过一篇php实现post请求的文章. 今天想到好久没有输出了,重新认识到输出的重要性.百般思索该写些什么?想来想去,想到了两点: 逐步熟练nodejs各种场景知识,针对mysql数据交互和f ...
- 在react项目中启用mobx的配置方法
1.安装插件 npm install --save-dev babel-preset-mobx mobx mobx-react 2.package.json配置 "dependencies& ...
- 数据中心网络架构的问题与演进 — 混合云与 VPC 专有网络
目录 文章目录 目录 前文列表 历史背景 混合云 Why hybrid cloud? 混合云市场 混合云的逻辑架构 混合云应用场景 灾难恢复 数据备份 负载扩容 应用部署 开发测试生产部署 混合云产品 ...
- DBUtil连接数据库
1. SQL server连接: 数据库不同架包就不同 SQL server 使用的架包是(sqljdbc4.jar) 2. Mysql (MariaDB同理) SQL server 使用的架包是(m ...
- JVM调优小结
JVM调优浅谈 https://www.cnblogs.com/andy-zhou/p/5327288.html 1.数据类型 java虚拟机中,数据类型可以分为两类:基本类型和引用类型. 基本类 ...
- switch语句 initialization of 'XXX' is skipped by 'case' label 原因及解决办法--块语句的作用
出错代码段: switch (t) { case 0: int a = 0; break; default: break; }编译时提示:“error C2361: initialization ...
- robotframework 接口测试 +RSA 加密
首先,实现RSA加密,需要用到pycrypto这个库,这个库又依赖openssl,所以需要先下载openssl,具体教程可以参考http://bbs.csdn.net/topics/392193545 ...