Skip to content

Latest commit

 

History

History
69 lines (56 loc) · 4.43 KB

ch4.md

File metadata and controls

69 lines (56 loc) · 4.43 KB

4 - 字符串

概览

  • 和 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 的?
    • 经过搜索,我发现这涉及后面的知识点——元表,此处先略去

Unicode 编码

Lua 提供了名叫 utf8 的标准库,用于支持对 UTF-8 字符串的操作。原字符串标准库 string 部分支持 utf8,但为了不产生混淆,这里我仅使用 utf8 库来处理 UTF-8 字符串。

  • utf8.len:返回 UTF-8 字符串的 code point 个数
    • 如果发现无效 UTF-8 字符,则返回 nil 和第一个无效字节的位置
  • utf8.char(...):类似 string.char
  • utf8.codepoint(s, i, j):类似 string.byte
  • utf8.offset(s, i):得到第 icode point字节位置
  • utf8.codes:用于 for in 遍历 UTF-8 字符串,每个条目为 字节位置 内部数值
  • 注意,utf8 中的大部分函数以字节为索引,而不是 code point