转载自:GitHub:pangliang/pangliang.github.com

需求

按字面个数来截取
函数(字符串, 开始位置, 截取长度)

utf8sub("你好1世界哈哈",,)    =    好1世界哈
utf8sub("1你好1世界哈哈",,) = 你好1世界
utf8sub("你好世界1哈哈",,) = 你好世界1
utf8sub("",,) =
utf8sub("øpø你好pix",,) = 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字符规律

字符串的首个byte表示了该utf8字符的长度

0xxxxxxx - 1 byte

110yxxxx - 192, 2 byte

1110yyyy - 225, 3 byte

11110zzz - 240, 4 byte

正确算法

 --
-- lua
-- 判断utf8字符byte长度
-- 0xxxxxxx - 1 byte
-- 110yxxxx - 192, 2 byte
-- 1110yyyy - 225, 3 byte
-- 11110zzz - 240, 4 byte
local function chsize(char)
if not char then
print("not char")
return
elseif char > then
return
elseif char > then
return
elseif char > then
return
else
return
end
end -- 计算utf8字符串字符数, 各种字符都按一个字符计算
-- 例如utf8len("1你好") => 3
function utf8len(str)
local len =
local currentIndex =
while currentIndex <= #str do
local char = string.byte(str, currentIndex)
currentIndex = currentIndex + chsize(char)
len = len +
end
return len
end -- 截取utf8 字符串
-- str: 要截取的字符串
-- startChar: 开始字符下标,从1开始
-- numChars: 要截取的字符长度
function utf8sub(str, startChar, numChars)
local startIndex =
while startChar > do
local char = string.byte(str, startIndex)
startIndex = startIndex + chsize(char)
startChar = startChar -
end local currentIndex = startIndex while numChars > and currentIndex <= #str do
local char = string.byte(str, currentIndex)
currentIndex = currentIndex + chsize(char)
numChars = numChars -
end
return str:sub(startIndex, currentIndex - )
end -- 自测
function test()
-- test utf8len
assert(utf8len("你好1世界哈哈") == )
assert(utf8len("你好世界1哈哈 ") == )
assert(utf8len(" 你好世 界1哈哈") == )
assert(utf8len("") == )
assert(utf8len("øpø你好pix") == ) -- test utf8sub
assert(utf8sub("你好1世界哈哈",,) == "好1世界哈")
assert(utf8sub("1你好1世界哈哈",,) == "你好1世界")
assert(utf8sub(" 你好1世界 哈哈",,) == "你好1世界 ")
assert(utf8sub("你好世界1哈哈",,) == "你好世界1")
assert(utf8sub("",,) == "")
assert(utf8sub("øpø你好pix",,) == "pø你好p") print("all test succ")
end test()

UTF8字符串在lua的截取和字数统计【转载】的更多相关文章

  1. [寒江孤叶丶的Cocos2d-x之旅_36]用LUA实现UTF8的字符串基本操作 UTF8字符串长度,UTF8字符串剪裁等

    原创文章,欢迎转载,转载请注明:文章来自[寒江孤叶丶的Cocos2d-x之旅系列] 博客地址:http://blog.csdn.net/qq446569365 一个用于UTF8字符串操作的类.功能比較 ...

  2. php字符串标点等字符截取不乱吗 封装方法

    方法一: /**   +----------------------------------------------------------  * 功能:字符串截取指定长度  * leo.li hen ...

  3. c++ 处理utf-8字符串

    c++的字符串中的每一个元素都是一个字节.所以在装入utf8字符串的时候,其实是按照一定的规则编码的. 字符的8位中 如果0开头 则自己就是一个单位. 1字节 0xxxxxxx  2字节 110xxx ...

  4. 11、多行文本最后一行显示省略号并截取文本字数(vue)

    1.首先通过css实现多行文本显示省略号: { height: 45px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-li ...

  5. UTF-8编码的字符串拆分成单字、获取UTF-8字符串的字符个数的代码及原理

    一.字符编码简介 1. ASCII码 在计算机内部,所有的信息最终都表示为一个二进制的字符串.每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(by ...

  6. [C++] zlatlcv: ATL字符串转换辅助库。能很方便的将UTF-8字符串转为TCHAR等字符串

    作者:zyl910 如今,UTF-8字符串的使用频率越来越多了.但是在VC中,不能直接处理UTF-8字符串,得专门去写UTF-8与窄字符串.宽字符串.TCHAR字符串相互转换的代码.不仅费时费力,而且 ...

  7. UTF8字符串转换为汉字 c#

    using System; /// <summary> /// UTF8字符串转换为汉字用的类 /// 转换如"\\u8d35"之类的字符串为对应的汉字 /// < ...

  8. 【转】UTF8字符串转换为汉字 c#,转自游戏开发主席

    using System; /// <summary> /// UTF8字符串转换为汉字用的类 /// 转换如"\\u8d35"之类的字符串为对应的汉字 /// < ...

  9. c语言判断是否是utf8字符串,计算字符个数

    #include <stdio.h> #include <string.h> #include <stdlib.h> /********************** ...

随机推荐

  1. SSO是什么?

    SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信仸的应用系统.它包括可以将这次主要的登录映射到其他应用中用亍同一个用户的登录的机制 ...

  2. sass / scss

    Sass 有两种语法规则(syntaxes),目前新的语法规则(从 Sass 3开始)被称为 “SCSS”( 时髦的css(Sassy CSS)),它是css3语法的的拓展级,就是说每一个语法正确的C ...

  3. HTTP basic 认证

    为了确保资源的非法访问,HTTP采用两种认证方式,一种为basic,另外一种为digest(摘要认证).basic是最基本也是最简单的一种认证方式.认证的过程大概可分为以下几个步骤:1. 用户请求受保 ...

  4. openerp发送给群组信息

    发送给群组 self.pool.get('mail.group').message_post(cr, uid, [1],             body=_('Welcome to ! Please ...

  5. Ubuntu解压缩zip,tar,tar.gz,tar.bz2

    ZIP zip可能是目前使用得最多的文档压缩格式.它最大的优点就是在不同的操作系统平台,比如Linux, Windows以及Mac OS,上使用.缺点就是支持的压缩率不是很高,而tar.gz和tar. ...

  6. 九度OJ 1183 守形数 (模拟)

    题目1183:守形数 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2663 解决:1424 题目描写叙述: 守形数是这样一种整数.它的平方的低位部分等于它本身. 比方25的平方是625. ...

  7. Web Service基础——四种客户端调用方式

    通过访问公网服务地址 http://www.webxml.com.cn/zh_cn/index.aspx 来演示四种不同的客户端调用方式 1. 生成客户端调用方式 1.1 Wsimport命令介绍 首 ...

  8. Mac环境 MySQL 和 MySQLWorkBench 破解版百度云下载

    最近有小伙伴下载,我正好保存有 正好分享一下 下载路径: Max环境下下载安装 1.下载完直接安装 MySQL安装后,这里可以查看 2.MySQLWorkBench安装完,桌面会有图标 打开后,用lo ...

  9. mybatis启动报错Result Maps collection already contains value forxxx

    ssm搭建过程中启动tomcat,报错: Cause: java.lang.IllegalArgumentException: Result Maps collection already conta ...

  10. iOS archive(归档)

    归档是一种很常用的文件储存方法,几乎任何类型的对象都能够被归档储存(实际上是一种文件保存的形式),浏览网上的一些资料后,并结合自己的一些经验,总结成此文. 一.使用archiveRootObject进 ...