5.字符串操作

5.字符串操作


5.1 知识点

知识回顾

  • 声明字符串
str1 = "双引号字符串"
str2 = '单引号字符串'

#获取字符串长度

  • # 获取的是字符串长度。更准确一点说,Lua 字符串本质上是一段字节序列,所以这里通常得到的是字节长度,不是肉眼看到的字符个数。
  • 英文、数字一般是 1 个字节,UTF-8 中文一般是 3 个字节。
str1 = "aBcdEfG字符串"
print(#str1) -- 16

这里不要把 # 当成“统计中文字符数量”的工具。它适合用来理解字符串底层长度,真要按字符数处理中文,后面要结合具体编码和项目里的字符串工具来做。

字符串多行打印

  • Lua 支持转义字符换行来多行打印。
print("123\n123")

输出:

123
123
  • 也可以使用 [[]] 包裹字符串来多行打印。
str1 = [[
  我是
韬
]]
print(str1)

输出:

  我是
韬

[[]] 这种写法在写大段文本、配置片段、调试输出时比较省事,不用一直手动写 \n

..和string.format方法进行字符串拼接

  • .. 用来做字符串拼接。
print("123" .. "456") -- 123456
str1 = 111
str2 = 222
print(str1 .. str2) -- 111222
  • string.format 可以通过占位符格式化字符串。
  • 常用几个先记住即可:
    • %d:整数
    • %f:小数
    • %s:字符串
print(string.format("我是韬老狮,我今年%d岁了", 18))

.. 适合简单拼接,string.format 适合格式比较固定、参数比较多的字符串。基础语法阶段先会用就行,性能和大量拼接的问题后面放到字符串机制里再讲。

tostring方法让别的类型转字符串

  • tostring 方法可以把其他类型转成字符串。
a = true
print(tostring(a)) -- true

实际写脚本时,拼接前最好确认变量是不是可能为 nil。如果不确定,可以先 tostring 一下,避免拼接时报错。

字符串库函数

str1 作为例子:

str1 = "abCdefgCd"

注意:

  1. 字符串库函数一般不会改变原字符串,而是返回处理后的新字符串。
  2. Lua 的索引是从 1 开始的。
  3. string.findstring.gsub 默认会按 Lua 的“匹配规则”处理。普通字符串用起来没什么感觉,遇到 .、+、% 这类特殊字符时要注意。

小写转大写方法string.upper 传入字符串

print(string.upper(str1)) -- ABCDEFGCD

大写转小写方法string.lower 传入字符串

print(string.lower(str1)) -- abcdefgcd

翻转字符串方法string.reverse 传入字符串

print(string.reverse(str1)) -- dCgfedCba

这里用普通英文字符串演示没问题。如果拿 UTF-8 中文字符串去反转,底层会按字节反转,结果很容易乱码。

字符串索引查找方法string.find 传入字符串和要查找的字符串 会返回起始和结束索引

print(string.find(str1, "Cde")) -- 3 5

这里先说一个容易混淆的点:string.find 第二个参数默认不是完全死板地按普通文本查找,而是会按 Lua 的匹配规则来理解。

可以先把“匹配规则”理解成:Lua 给字符串查找准备的一套特殊写法。普通内容比如 "Cde" 没有特殊符号,所以看起来就是普通查找。

但有些字符在这套规则里有特殊含义,比如 . 表示“任意一个字符”。所以如果直接查 ".",不一定是在查真正的点号。

local str3 = "abc.def"
print(string.find(str3, "."))          -- 1 1,"." 在匹配规则里表示任意字符
print(string.find(str3, "%."))         -- 4 4,用 "%." 查真正的点号
print(string.find(str3, ".", 1, true)) -- 4 4,第四个参数 true 表示按普通文本查找

截取字符串方法string.sub 传入字符串和起始结束索引 不传结束索引默认到传入的字符串尾

print(string.sub(str1, 3)) -- CdefgCd
print(string.sub(str1, 3, 4)) -- Cd

字符串重复方法string.rep 传入字符串和重复次数

print(string.rep(str1, 2)) -- abCdefgCdabCdefgCd

字符串修改方法string.gsub 传入要修改的字符和替换后的字符 返回修改后的字符串和修改了几处

print(string.gsub(str1, "Cd", "**")) -- ab**efg**   2

string.gsub 也会按 Lua 的匹配规则查找内容。上面 "Cd" 没有特殊字符,所以可以先当普通替换理解。它会返回两个值:第一个是替换后的新字符串,第二个是替换次数。

字符转字节值方法string.byte 传入字符串和要转字节值的字符索引

str1 = string.byte("Lua", 1) -- 转换 L 为字节值
print(str1) -- 76

这里以前常说“转 ASCII 码”,在 "Lua" 这种英文字符串上这么理解没什么问题。但更准确地说,string.byte 拿到的是字符对应的字节值。

字节值转字符方法string.char 传入字节值

print(string.char(str1)) -- L

5.2 知识点代码

Lesson5_字符串操作.lua

print("**********字符串操作************")

print("**********知识回顾************")
-- 声明字符串
str1 = "双引号字符串"
str2 = '单引号字符串'

print("**********知识点一 获取字符串长度************")
str1 = "aBcdEfG字符串"
-- Lua 字符串本质上是一段字节序列
-- # 获取的通常是字节长度,不是肉眼看到的字符个数
-- UTF-8 中文一般是 3 个字节
-- 英文字符一般是 1 个字节
print(#str1) -- 16

print("**********知识点二 字符串多行打印************")
-- Lua 支持转义字符换行来多行打印
print("123\n123")
-- 123
-- 123

-- 也可以使用 [[]] 包裹字符串多行打印
str1 = [[
    我是
韬
]]
print(str1)
--     我是
-- 韬

print("**********知识点三 字符串拼接************")
-- .. 字符串拼接
print("123" .. "456") -- 123456

str1 = 111
str2 = 222
print(str1 .. str2) -- 111222

-- string.format 可以通过占位符格式化字符串
-- %d:整数
-- %f:小数
-- %s:字符串
print(string.format("我是韬老狮,我今年%d岁了", 18))

print("**********知识点四 别的类型转字符串************")
-- tostring 方法传入其他类型的变量,可以转成字符串
a = true
print(tostring(a)) -- true

print("**********知识点五 字符串库函数************")
str1 = "abCdefgCd"

-- 注意:
-- 1. 字符串库函数一般不会改变原字符串,而是返回处理后的新字符串
-- 2. Lua 的索引是从 1 开始的
-- 3. string.find 和 string.gsub 默认会按 Lua 的匹配规则处理
--    普通字符串用起来没什么感觉,遇到 .、+、% 这类特殊字符时要注意

-- 小写转大写方法 string.upper,传入字符串
print(string.upper(str1)) -- ABCDEFGCD

-- 大写转小写方法 string.lower,传入字符串
print(string.lower(str1)) -- abcdefgcd

-- 翻转字符串方法 string.reverse,传入字符串
-- 普通英文字符串演示没问题,UTF-8 中文字符串按字节反转容易乱码
print(string.reverse(str1)) -- dCgfedCba

-- 字符串索引查找方法 string.find,传入字符串和要查找的字符串
-- 会返回起始和结束索引
print(string.find(str1, "Cde")) -- 3 5

-- string.find 第二个参数默认会按 Lua 的匹配规则理解
-- "." 在匹配规则里表示任意一个字符,不是普通点号
local str3 = "abc.def"
print(string.find(str3, "."))          -- 1 1,"." 在匹配规则里表示任意字符
print(string.find(str3, "%."))         -- 4 4,用 "%." 查真正的点号
print(string.find(str3, ".", 1, true)) -- 4 4,第四个参数 true 表示按普通文本查找

-- 截取字符串方法 string.sub,传入字符串和起始结束索引
-- 不传结束索引默认到传入的字符串尾
print(string.sub(str1, 3))    -- CdefgCd
print(string.sub(str1, 3, 4)) -- Cd

-- 字符串重复方法 string.rep,传入字符串和重复次数
print(string.rep(str1, 2)) -- abCdefgCdabCdefgCd

-- 字符串修改方法 string.gsub
-- 传入要修改的字符和替换后的字符,返回修改后的字符串和修改了几处
print(string.gsub(str1, "Cd", "**")) -- ab**efg**	2

-- 字符转字节值方法 string.byte,传入字符串和要转字节值的字符索引
-- 这里用的是英文字符 L,所以结果可以按 ASCII 码理解
str1 = string.byte("Lua", 1) -- 转换 L 为字节值
print(str1) -- 76

-- 字节值转字符方法 string.char,传入字节值
print(string.char(str1)) -- L


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏