- 和 Python 一样,Lua 的字符串是**不可变(immutable)**值,意味着如果你想要修改字符串,必须根据原字符串创建一个新字符串,然后再把新字符串赋值给原字符串
- 使用长度操作符
#
来获得字符串的长度 - 使用连接操作符
..
来连接两个字符串,该操作不会影响原字符串的值- 如果操作数为
number
,那么 Lua 会自动将其转换成字符串- 在书写的时候,需要加空格分隔,否则会被识别为小数点,如
12..34
应当为12 .. 34
- 在书写的时候,需要加空格分隔,否则会被识别为小数点,如
- 如果操作数为
除了支持 C 语言风格的转义字符以外,Lua 还支持 UTF-8 字符的声明,格式为 "\u{xxx}"
,其中 xxx
为 16 进制数字
- 使用一对双方括号
[[ xxx ]]
来声明多行字符串常量- 任何其中的转义字符都不会被转义
- 如果
[[
之后紧跟着一个换行符,则它会被忽略,这样做可以使代码更美观 - 如果字符串中包含
]]
或多行注释,为了防止字符串在中间断开,可以使用[==[ xxx ]==]
,其中=
的数量任意,但前后必须匹配- 这一做法对于多行注释同样适用
- 对于任何有字符串参与的算术运算,字符串会被自动转换成浮点数
- 如
"10" + 1
的结果为11.0
,但不推荐这种写法
- 如
- 对于比较运算,则不会进行自动转换,对于两个字符串的比较,默认按照字典序进行
- 如果将字符串与数值进行比较,则会报错
- 使用函数
tonumber
来显式地将字符串转换为数值,它包含一个可选的进制参数,默认为十进制- 这里我有点好奇可选参数是怎么实现的,因为经过搜索发现,Lua 并不支持函数重载
- 答案是,在调用函数时,未传递的参数默认会被赋
nil
,这样就能实现默认或可选参数的效果了 - 感想:引入
nil
这样的特殊值很有用!
这里列举一些常用函数。
string.len
:返回字符串的长度,等价于#
string.rep(s, n)
:将字符串重复n
次string.reverse
:将字符串反转string.lower
:将所有大写字母转换成小写字母string.upper
:将所有小写字母转换成大写字母string.sub(s, i, j)
:提取从第i
到第j
个字符组成的子串,支持负数索引string.char(...)
:将若干个整数转换为字符串然后依次连接string.byte(s, i, j)
:得到指定子串的内部数值表示,返回值为表string.byte(s, i)
:得到第i
个字符的内部数值表示- 这里我很好奇
string.byte("abc", 1, -1)
的返回值,于是用type
函数看了一下,结果是number
- 原来多返回值函数的返回值不是一个
table
吗? - 问了 ChatGPT,发现该类型实际上是多返回值中的第一个值的类型
- 如果想要返回表,需要手动套上
{}
- 话说回来,多返回值函数的返回值个数一般来说是事先确定的,
string.byte
是如何实现可变个数的返回值的呢? - 再次询问 GPT,答案是使用
unpack
函数!
string.find(s, pattern)
:用于搜索pattern
字符串,在s
中第一次出现的位置- 如果找到了,返回起始和终止字符在
s
中的索引(从1
开始),否则返回nil
- 如果找到了,返回起始和终止字符在
string.gsub(s, pattern, sub)
:将s
中所有满足pattern
的子串都替换为sub
- 语法糖:
string.sub(s, i, j)
可以简写成s:sub(i, j)
- 我的疑惑是,Lua 怎么知道
sub
是属于string
的? - 经过搜索,我发现这涉及后面的知识点——元表,此处先略去
- 我的疑惑是,Lua 怎么知道
Lua 提供了名叫 utf8
的标准库,用于支持对 UTF-8 字符串的操作。原字符串标准库 string
部分支持 utf8
,但为了不产生混淆,这里我仅使用 utf8
库来处理 UTF-8 字符串。
utf8.len
:返回 UTF-8 字符串的 code point 个数- 如果发现无效 UTF-8 字符,则返回
nil
和第一个无效字节的位置
- 如果发现无效 UTF-8 字符,则返回
utf8.char(...)
:类似string.char
utf8.codepoint(s, i, j)
:类似string.byte
utf8.offset(s, i)
:得到第i
个 code point 的字节位置utf8.codes
:用于for in
遍历 UTF-8 字符串,每个条目为字节位置 内部数值
- 注意,
utf8
中的大部分函数以字节为索引,而不是 code point