跳转至

字符串处理

一、Lua 字符串介绍

关于字符串,Lua 提供了一些灵活且强大的功能,一些入门知识如下:

1.1 字符串定义

在 Lua 中,字符串可以用单引号 ' 或双引号 " 来定义。例如:

local str1 = 'Hello, World!'

local str2 = "Hello, Lua!"

也可以定义多行字符串: local str3 = [[ heello

abcdef

]]

1.2 字符串连接

Lua 使用 .. 操作符进行字符串连接。例如:

local greeting = "Hello"

local name = "World"

local message = greeting .. ", " .. name .. "!" -- 结果为 "Hello, World!"

1.3 字符串长度

可以使用 # 操作符获取字符串的长度。例如:

local length = #"Hello, World!" -- 结果为 13

综上所述,Lua 的字符串功能强大且易于使用,非常适合嵌入式开发中的文本处理需求。通过灵活运用这些功能,可以有效地处理和操作字符串数据。

二、演示功能概述

本文使用 Air780EP 核心板,对字符串进行定义、连接、计算长度、格式化输出以及分割等处理,并通过日志观察的方式验证实验结果。

三、准备硬件环境

参考:硬件环境清单第二章节内容,准备以及组装好硬件环境。

四、软件环境

“凡事预则立,不预则废。”在详细阐述本功能示例之前,我们需先精心筹备好以下软件环境。

1. Luatools工具

2. 内核固件文件(底层core固件文件):LuatOS-SoC_V2002_Air780EP;参考项目使用的内核固件

3. luatos需要的脚本和资源文件

脚本和资源文件:点击此处查看与下载

lib脚本文件:使用Luatools烧录时,勾选 添加默认lib 选项,使用默认lib脚本文件;

准备好软件环境之后,接下来查看如何烧录项目文件到Air780EP核心板,将本篇文章中演示使用的项目文件烧录到Air780EP核心板中。

五、代码示例介绍

5.1 完整程序清单

注:完整复制后保存为 main.lua,可直接使用

-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "stringTest"
VERSION = "2.0.0"

--[[
本demo演示 string字符串的基本操作
1\. lua的字符串是带长度, 这意味着, 它不依赖0x00作为结束字符, 可以包含任意数据
2\. lua的字符串是不可变的, 就不能直接修改字符串的一个字符, 修改字符会返回一个新的字符串
]]

-- sys库是标配
_G.sys = require("sys")

sys.taskInit(function ()
    sys.wait(1000) -- 免得看不到日志
    local tmp

    ----------------------------------------------
    --================================================
    -- 字符串的声明和生成
    --================================================


    local str = "123455"     -- 常量声明
    log.info("str", str)     -- 测试字符串输出:123455

    -- 合成式
    str = string.char(0x31, 0x32, 0x33, 0x34)  --0x31为字符 1的ASCII码
    log.info("str", str)  --日志输出:1234                   
    -- lua的字符串可以包含任意数据, 包括 0x00
    str = string.char(0x12, 0x00, 0xF1, 0x3A)
    log.info("str", str:toHex()) -- 注意, 这里用toHex(), 因为包含了不可见字符,日志输出:1200F13A        8(其中8为输出字符串长度)
    -- 使用转义字符
    str = "\x00\x12ABC"                         -- 字符串中的\x表示十六进制转义序列                                                                
    log.info("str", str:toHex()) -- 注意, 这里用toHex(), 因为包含了不可见字符,日志输出:0012414243        10 (其中41,42,43分别分字符 ABC的ASCII值的十六进制形式,10为输出字符串长度)
    str = "ABC\r\n\t"
    log.info("str", str:toHex()) -- 注意, 这里用toHex(), 因为包含了不可见字符,日志输出:4142430D0A09        12(其中0D为\r回车键值的ASCII值的十六进制形式,
                                 --0A为\n换行键值的ASCII值的十六进制形式,\t 是一个转义字符,表示一个水平制表符(Tab))



    -- 解析生成
    str = string.fromHex("AABB00EE")                                                                                        
    log.info("str", str:toHex())               --日志输出:AABB00EE        8
    str = string.fromHex("393837363433")       --将字符串转换为十六进制形式
    log.info("str", #str, str)                 --日志输出:6        987643(其中6为输出字符长度,987643为输出字符串)

    -- 连接字符串, 操作符 ".."
    str = "123" .. "," .. "ABC"  --将3段字符串连接起来
    log.info("str", #str, str)                 --日志输出:7        123,ABC(其中7为输出字符长度,123,ABC为连接后的字符串)


    -- 格式化生成
    str = string.format("%s,%d,%f", "123", 45678, 1.5)--格式化输出,        %s为字符串输出,%d为十进制输出,%f为浮点形式输出                        
    log.info("str", #str, str)                 --日志输出:18        123,45678,1.500000


    --================================================
    -- 字符串的解析与处理
    --================================================
    -- 获取长度
    str = "1234567"
    log.info("str", #str)                      --日志输出:7 为字符串长度
    -- 获取字符串的HEX字符串显示
    log.info("str", str:toHex())               --日志输出:31323334353637        14(用字符格式输出十六进制)

    -- 获取指定位置的值, 注意lua的下标是1开始的
    str = "123ddss"
    log.info("str[1]", str:byte(1))            --日志输出:49         (字符1,对应十进制ASCII值)
    log.info("str[4]", str:byte(4))            --日志输出: 100         (字符d,对应十进制ASCII值)
    log.info("str[1]", string.byte(str, 1))    --日志输出:49   (str位置1的字符,也是数字1)
    log.info("str[4]", string.byte(str, 4))    --日志输出: 100         (str位置4的字符,也是数字d)

    -- 按字符串分割
    str = "12,2,3,4,5"
    tmp = str:split(",")
    log.info("str.split", #tmp, tmp[1], tmp[3])  --日志输出:5        12        3
    tmp = string.split(str, ",") -- 与前面的等价
    log.info("str.split", #tmp, tmp[1], tmp[3])  --日志输出:5        12        3
    str = "/tmp//def/1234/"
    tmp = str:split("/")
    log.info("str.split", #tmp, json.encode(tmp)) --日志输出:3        ["tmp","def","1234"]

    -- 2023.04.11新增的, 可以保留空的分割片段
        --在 Lua 中,str:split("/", true) 语句表示将字符串 str 按照字符 "/" 进行分割,并且 true 参数通常用于表示保留空字符串(这取决于具体的 split 函数实现,因为 Lua 标准库中没有内置的 split 函数)。根据你的描述,输出结果是 6 ["","tmp","","def","1234",""]。这是因为:
    --假设 str 是 "/tmp//def/1234/",在这种情况下,字符串以 "/" 开头和结尾,并且有连续的 "/"。
    --split 函数将字符串分割成多个部分,每个 "/" 都会作为一个分割符。
    --因为 true 参数表示保留空字符串,所以在分割过程中,连续的 "/" 和开头、结尾的 "/" 都会导致空字符串被保留。

    tmp = str:split("/", true) 
    log.info("str.split", #tmp, json.encode(tmp)) --日志输出:6        ["","tmp","","def","1234",""]

    -- 更多资料
    -- https://wiki.luatos.com/develop/hex_string.html
    -- https://wiki.luatos.com/_image/lua53doc/manual.html#3.4
end)
-- 这里演示4G模块上网后,会自动点亮网络灯,方便用户判断模块是否正常开机
sys.taskInit(function()
    while true do
        sys.wait(6000)
                if mobile.status() == 1 then
                        gpio.set(27, 1)  
                else
                        gpio.set(27, 0) 
                        mobile.reset()
        end
    end
end)
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

六、功能验证

注:详细日志输出内容,在程序中有增强注释说明,请详细查看。

总结

至此,我们已使用 Air780EP 开发板验证了字符串的相关操作功能。

给读者的话

本篇文章由肇朔开发;

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

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

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

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

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