跳转至

字符串处理

一、简介

  • 比特( 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.编码格式转换库

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()后打印。

给读者的话

本篇文章由杨超开发;

本篇文章描述的内容,如果有错误、细节缺失、细节不清晰或者其他任何问题,总之就是无法解决您遇到的问题;

请登录合宙技术交流论坛,点击文档找错赢奖金-Air724UG-LuatOS-软件指南-通用工具库-字符串处理

用截图标注+文字描述的方式跟帖回复,记录清楚您发现的问题;

我们会迅速核实并且修改文档;

同时也会为您累计找错积分,您还可能赢取月度找错奖金!