字符串处理
一、简介
- 比特( bit)是二进制单位( binary unit)或二进制数字(binary digit)的缩写。
- pack 库支持将一系列数据按照格式字符转化为 lua 字符串或者将 lua 字符串按照格式字符转化成一系列值。
- utf8、 ucs2、 gb2312 编码是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
以上都是常见的数据格式。需要进行运算、转换等格式化处理。
二、演示功能概述
本教程教你如何用 Air724 开发板,对字符串进行定义、连接、计算长度、格式化输出以及分割等处理,并通过日志观察的方式验证实验结果。
三、准备硬件环境
3.1 开发板准备
使用 EVB_Air724 开发板,如下图所示:
淘宝购买链接:Air724UG-NFM 开发板淘宝购买链接 ;
此开发板的详细使用说明参考:Air724UG 产品手册 中的《EVB_Air724UG_AXX 开发板使用说明》,写这篇文章时最新版本的使用说明为:《EVB_Air724UG_A14 开发板使用说明》;开发板使用过程中遇到任何问题,可以直接参考这份使用说明文档。
api:https://doc.openluat.com/wiki/21?wiki_page_id=2068
3.2 数据通信线
USB 数据线一根(micro USB)。
3.3 PC 电脑
WIN7 以及以上版本的 WINDOWS 系统。
3.4 SIM 卡
中国大陆环境下,可以上网的 SIM 卡。一般来说,使用移动,电信,联通的物联网卡或者手机卡都行。
3.5 组装硬件环境
USB 数据线插入 USB 口,另一端与电脑相连,拨码开关全部拨到 ON,串口切换开关选择 UART1,USB 供电的 4V 对应开关拨至 ON 档,SIM 卡放到 SIM 卡槽中锁紧,如下图所示。
四、准备软件环境
4.1 下载调试工具
使用说明参考:Luatools 下载和详细使用
4.2 源码及固件
1.底层 core 下载
下载底层固件,并解压
链接:https://docs.openluat.com/air724ug/luatos/firmware/
如下图所示,红框的是我们要使用到的
2.本教程使用的 demo 见附件:
4.3 下载固件和脚本到开发板中
打开 Luatools,开发板上电开机,如开机成功 Luatools 会打印如下信息。
点击项目管理测试选项。
进入管理界面,如下图所示。
- 点击选择文件,选择底层固件,我的文件放在 D:\luatOS\Air724 路径中
- 点击增加脚本或资源文件,选择 之前下载的程序源码,如下图所示。
- 点击下载底层和脚本,下载完成如下图所示。
五、代码示例介绍
5.1 API 说明
1.bit
2.扩展库 pack
3.编码格式转换库
本文用到的API这里不做详细说明,可通过点击右侧链接查看:bit API pack API common API
5.2 main.lua 代码
本代码为主程序脚本,系统启动后首先会对 4G 网络进行配置,等待网络连接成功,然后加载测试模块。
5.3 testFormatString.lua 代码
本代码为测试脚本,加载格式化字符串功能测试模块。
- 介绍 bit 库的使用,并打印出来,local function bittest()。
- 扩展库 pack 的功能演示,local function packedtest()。
- sting 库几个接口的使用演示,local function stringtest()。
- 将二进制数字转化为十六进制,并输出转换后的十六进制数字串,每个字节之间用分隔符隔开打印出十六进制数字串,local function binstohexs(binstring,s)
- 将十六进制数转换为二进制数,并储存在数组中,输出转化后的二进制数,local function hexstobins(hexstring)
- unicode 小端编码 转化为 gb2312 编码,并打印出 gb2312 编码数据,local function ucs2ToGb2312(ucs2s) gb2312 编码 转化为 unicode 十六进制小端编码数据并打印,local function gb2312ToUcs2(gb2312num)
- unicode 大端编码 转化为 gb2312 编码,并打印出 gb2312 编码数据, 大端编码数据是与小端编码数据位置调换,local function ucs2beToGb2312(ucs2s)
- gb2312 编码 转化为 unicode 大端编码,并打印出 unicode 大端编码,function gb2312ToUcs2be(gb2312s)
- unicode 小端编码 转化为 utf8 编码,并打印出 utf8 十六进制编码数据,local function ucs2ToUtf8(usc2)
- utf8 编码 转化为 gb2312 编码,并打印出 gb2312 编码数据,local function utf8ToGb2312(utf8s)
--- 模块功能:格式化字符串功能测试.
-- @author openLuat
-- @module formatString.testFormatString
-- @license MIT
-- @copyright openLuat
-- @release 2018.03.27
module(...,package.seeall)
require"common"
require"utils"
--[[函数名:bittest
功能:介绍bit库的使用,并打印出来
返回值:无--]]
local function bittest()
print("bittest:") --程序运行开始标记
print(bit.bit(2))--参数是位数,作用是1向左移动两位,打印出4
print(bit.isset(5,0))--第一个参数是是测试数字,第二个是测试位置。从右向左数0到7。是1返回true,否则返回false,该返回true
print(bit.isset(5,1))--打印false
print(bit.isset(5,2))--打印true
print(bit.isset(5,3))--返回返回false
print(bit.isclear(5,0))--与上面的相反
print(bit.isclear(5,1))
print(bit.isclear(5,2))
print(bit.isclear(5,3))
print(bit.set(0,0,1,2,3))--在相应的位数置1,打印15
print(bit.clear(5,0,2)) --在相应的位置置0,打印0
print(bit.bnot(5))--按位取反
print(bit.band(1,1))--与,--输出1
print(bit.bor(1,2))--或,--输出3
print(bit.bxor(1,2))--异或,相同为0,不同为1
print(bit.lshift(1,2))--逻辑左移,“100”,输出为4
print(bit.rshift(4,2))--逻辑右移,“001”,输出为1
print(bit.arshift(2,2))--算数右移,左边添加的数与符号有关,输出为0
end
--[[
函数名:packedtest
功能:扩展库pack的功能演示
参数:无
返回值:无
--]]
local function packedtest()
--[[将一些变量按照格式包装在字符串.'z'有限零字符串,'p'长字节优先,'P'长字符优先,
'a'长词组优先,'A'字符串型,'f'浮点型,'d'双精度型,'n'Lua 数字,'c'字符型,'b'无符号字符型,'h'短型,'H'无符号短型
'i'整形,'I'无符号整形,'l'长符号型,'L'无符号长型,">"表示大端,"<"表示小端。]]
print("pcak.pack test:")
print(string.toHex(pack.pack(">H",0x3234)))
print(string.toHex(pack.pack("<H",0x3234)))
--字符串,无符号短整型,字节型,打包成二进制字符串。由于二进制不能输出,所以转化为十六进制输出。
print(string.toHex(pack.pack(">AHb","LUAT",100,10)))
print("pack.unpack test:")
local stringtest = pack.pack(">AHb","luat",999,10)
--"nextpos"解析开始的位置,解析出来的第一个值val1,第二个val2,第三个val3,根据后面的格式解析
--这里的字符串要截取出来,如果截取字符串,后面的短整型和一个字节的数都会被覆盖。
nextpox1,val1,val2 = pack.unpack(string.sub(stringtest,5,-1),">Hb")
--nextpox1表示解包后最后的位置,如果包的长度是3,nextpox1输出就是4。匹配输出999,10
print(nextpox1,val1,val2)
end
--[[
短整型 占2个字节
长整型 占用4个字节(32位)
double型 占4个字节
long double型 占8个字节
数据类型 取值范围
整型 [signed]int -2147483648~+2147483648
无符号整型unsigned[int] 0~4294967295
短整型 short [int] -32768~32768
无符号短整型unsigned short[int] 0~65535
长整型 Long int -2147483648~+2147483648
无符号长整型unsigned [int] 0~4294967295
字符型[signed] char -128~+127
无符号字符型 unsigned char 0~255
不支持小数类型 --]]
--[[
函数名:stringtest
功能:sting库几个接口的使用演示
参数:无
返回值:无--]]
local function stringtest()
print("stringtest:")
--注意string.char或者string.byte只针对一个字节,数值不可大于256
print(string.char(97,98,99))--将相应的数值转化为字符
print(string.byte("abc"),2) --第一个参数是字符串,第二个参数是位置。功能是:将字符串中所给定的位置转化为数值
local i=100
local string1="luat100great"
print("string.format\r\n",string.format("%04d//%s",i,string1))--[[指示符后的控制格式的字符可以为:十进制'd';十六进制'x'
八进制'o';浮点数'f';字符串's',控制格式的个数与后面的参数个数一致。功能:按照特定格式输出参数。--]]
--打印出"luat great"
print("string.gsub\r\n",string.gsub("luat is","is","great"))--第一个参数是目标字符串,第二个参数是标准字符串,第三个是待替换字符串
--打印出目标字符串在查找字符串中的首尾位置
print("string.find\r\n",string.find(string1,"great"))
--匹配字符串,加()指的是返回指定格式的字符串,截取字符串中的数字
print("string.match\r\n",string.match(string1,"luat(%d+)great"))
--截取字符串,第二个参数是截取的起始位置,第三个是终止位置。
print("string.sub\r\n",string.sub(string1,1,4))
end
--[[函数名:bitstohexs()
功能:将二进制数字转化为十六进制,并输出转换后的十六进制数字串,每个字节之间用分隔符隔开
打印出十六进制数字串
参数:第一个参数二进制数字,第二个是分隔符
返回值: --]]
local function binstohexs(binstring,s)
print(string.toHex(binstring,s)) --调用了基本库中的common库,输出十六进制数字串
end
--[[函数名: hexstobits
功能:将十六进制数转换为二进制数,并储存在数组中,输出转化后的二进制数
参数:十六进制数
返回值: --]]
local function hexstobins(hexstring)--将十六进制数字转化为二进制字符串
print(string.fromHex(hexstring)) --注意二进制中有些是可打印可见的,有些则不是
end
--[[
函数名:ucs2ToGb2312
功能 :unicode小端编码 转化为 gb2312编码,并打印出gb2312编码数据
参数 :
ucs2s:unicode小端编码数据,注意输入参数的字节数
返回值:
]]
local function ucs2ToGb2312(ucs2s)
print("ucs2ToGb2312")
local gd2312num = common.ucs2ToGb2312(ucs2s)--调用的是common.ucs2ToGb2312,返回的是编码所对应的字符串
print("gb2312 code:",gd2312num)
end
--[[
函数名:gb2312ToUcs2
功能 :gb2312编码 转化为 unicode十六进制小端编码数据并打印
参数 :
gb2312s:gb2312编码数据,注意输入参数的字节数
返回值:
]]
local function gb2312ToUcs2(gd2312num)
print("gb2312ToUcs2")
local ucs2num=common.gb2312ToUcs2(gd2312num)
print("unicode little-endian code:"..string.toHex(ucs2num))--要将二进制转换为十六进制,否则无法输出
end
--[[
函数名:ucs2beToGb2312
功能 :unicode大端编码 转化为 gb2312编码,并打印出gb2312编码数据,
大端编码数据是与小端编码数据位置调换
参数 :
ucs2s:unicode大端编码数据,注意输入参数的字节数
返回值:
]]
local function ucs2beToGb2312(ucs2s)
print("ucs2beToGb2312")
local gd2312num=common.ucs2beToGb2312(ucs2s) --转化后的数据直接变成字符可以直接输出
print("gb2312 code :"..gd2312num)
end
--[[
函数名:gb2312ToUcs2be
功能 :gb2312编码 转化为 unicode大端编码,并打印出unicode大端编码
参数 :
gb2312s:gb2312编码数据,注意输入参数的字节数
返回值:unicode大端编码数据
]]
function gb2312ToUcs2be(gb2312s)
print("gb2312ToUcs2be")
local ucs2benum=common.gb2312ToUcs2be(gb2312s)
print("unicode big-endian code :"..string.toHex(ucs2benum))
end
--[[
函数名:ucs2ToUtf8
功能 :unicode小端编码 转化为 utf8编码,并打印出utf8十六进制编码数据
参数 :
ucs2s:unicode小端编码数据,注意输入参数的字节数
返回值:
]]
local function ucs2ToUtf8(usc2)
print("ucs2ToUtf8")
local utf8num=common.ucs2ToUtf8(usc2)
print("utf8 code:"..string.toHex(utf8num))
end
--[[
函数名:utf8ToGb2312
功能 :utf8编码 转化为 gb2312编码,并打印出gb2312编码数据
参数 :
utf8s:utf8编码数据,注意输入参数的字节数
返回值:
]]
local function utf8ToGb2312(utf8s)
print("utf8ToGb2312")
local gb2312num=common.utf8ToGb2312(utf8s)
print("gb2312 code:"..gb2312num)
end
--[[ 函数调用--]]
bittest()
packedtest()
stringtest()
--[[测试程序,接口举例,用模拟器就可以直接测试,以“我”为例--]]
binstohexs("ab")
hexstobins("3132")
ucs2ToGb2312(string.fromHex("1162")) --"1162"是"我"字的ucs2编码,这里调用了string.fromHex将参数转化为二进制,也就是两个字节。
gb2312ToUcs2(string.fromHex("CED2")) --"CED2"是"我"字的gb22312编码
ucs2beToGb2312(string.fromHex("6211"))--"6211"是"我"字的ucs2be编码
gb2312ToUcs2be(string.fromHex("CED2"))
ucs2ToUtf8(string.fromHex("1162"))
utf8ToGb2312(string.fromHex("E68891"))--"E68891"是"我"字的utf8编码
六、开机调试
6.1 开发板开机
连接好硬件并下载固件后,启动 Luatools 软件,系统运行信息将显示在界面中。红框中为开发板连接到 PC 机后正常打印的信息,如下图所示。
6.2 功能调试
1.介绍 bit 库的使用,并打印出来,local function bittest()。
2.扩展库 pack 的功能演示,local function packedtest()。
3.sting 库几个接口的使用演示,local function stringtest()。
七、常见问题
7.1 为什么字符串打印为空?
原因是字符串里有不可见字符比如“空字符(Null)”,解决方式 toHex()后打印。