跳转至

字符串处理

一、简介

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