Skip to content

Lua 字符串

在 Lua 中,字符串(string)是不可变(immutable)的字节序列。字符串可以包含字符,包括嵌入的零和控制字符。Lua 高效地处理字符串,并提供了一个强大的 string 库用于字符串操作(manipulation)。

字符串可以使用单引号、双引号或长方括号定义,用于多行字符串:

  • 单引号:'Hello Lua'
  • 双引号:"Hello Lua"
  • 长方括号:[[一个多行 字符串示例。]] 或 [=[另一个带有 [=[嵌套方括号]=] 的长字符串。]=]

字符串字面量示例:

local string1 = "Lua"
print("String 1 is: " .. string1)
local string2 = 'Tutorial'
print("String 2 is: " .. string2)
local string3 = [[
A multi-line string
for Lua.
]]
print("String 3 is:\n" .. string3)

运行上述程序后,输出将是:

String 1 is: Lua
String 2 is: Tutorial
String 3 is:
A multi-line string
for Lua.

在由单引号或双引号界定的字符串中,可以使用转义序列(escape sequences)来表示特殊字符。长方括号字符串不解释转义序列(开头处的换行规则除外)。

转义序列描述
\a响铃(警报)
\b退格
\f换页
\n换行
\r回车
\t水平制表符
\v垂直制表符
\反斜杠
”双引号
’单引号
[左方括号(如果在模式中使用 [[ 则需要,通常不在字符串字面量中使用)
]右方括号(同上)
\ddd十进制值 ddd 对应的字符(例如,\065 是 ‘A’)
\xhh十六进制值 hh 对应的字符(例如,\x41 是 ‘A’)
\u{XXX}Unicode 码点 XXX 的 UTF-8 序列(Lua 5.3+)

Lua 的 string 库提供了一套全面的函数用于字符串操作。请记住,字符串是不可变的;这些函数返回新的字符串,而不是修改原始字符串。

函数签名用途
string.upper(s)返回一个新字符串,其中 s 中的所有小写字母都转换为大写。
string.lower(s)返回一个新字符串,其中 s 中的所有大写字母都转换为小写。
string.gsub(s, pattern, replacement [, n])返回一个新字符串,其中 s 中 pattern 的出现被 replacement 替换。n 可选地限制替换次数。
string.find(s, pattern [, init [, plain]])返回 s 中第一个匹配 pattern 的起始和结束索引(从 init 开始搜索)。如果未找到,则返回 nil。如果 plain 为 true,则执行字面搜索。
string.reverse(s)返回 s 的反转新字符串。
string.format(formatstring, ...)返回一个格式化字符串,类似于 C 语言的 sprintf。
string.char(...)返回由给定整数 ASCII/字节值对应的字符组成的字符串。
string.byte(s [, i [, j]])返回字符 s[i]、s[i+1]、…、s[j] 的数值字节码。i 默认值为 1,j 默认值为 i。
string.len(s)返回字符串 s 的长度(以字节为单位)。(与 #s 运算符相同)。
string.rep(s, n [, sep])返回一个字符串,它是字符串 s 的 n 次重复,可选地由 sep 分隔(sep 参数在 Lua 5.4+ 中可用)。
string.sub(s, i [, j])返回从索引 i 开始到索引 j 结束的 s 子字符串;i 和 j 可以是负数。
string.match(s, pattern [, init])类似于 string.find,但在成功时返回从 pattern 中捕获的子字符串,如果无匹配项则返回 nil。

让我们看一些示例:

local my_string = "Hello Lua World!"
print("Uppercase:", string.upper(my_string)) -- HELLO LUA WORLD!
print("Lowercase:", string.lower(my_string)) -- hello lua world!
local text = "Lua is fun, Lua is powerful."
local new_text = string.gsub(text, "Lua", "LuaLang")
print("Replaced text:", new_text) -- LuaLang is fun, LuaLang is powerful.
local replaced_once = string.gsub(text, "Lua", "LuaLang", 1)
print("Replaced once:", replaced_once) -- LuaLang is fun, Lua is powerful.

查找子字符串(string.find)和反转(string.reverse)

Section titled “查找子字符串(string.find)和反转(string.reverse)”
local phrase = "Lua Tutorial"
local start_index, end_index = string.find(phrase, "Tutorial")
if start_index then
print(string.format("Found 'Tutorial' from index %d to %d", start_index, end_index)) -- 在索引 5 到 12 找到 'Tutorial'
end
local reversed_phrase = string.reverse(phrase)
print("Reversed phrase:", reversed_phrase) -- lairotuT auL
local name = "Alice"
local score = 100
local average = 95.756
local formatted1 = string.format("Player: %s, Score: %d", name, score)
print(formatted1) -- Player: Alice, Score: 100
local formatted2 = string.format("Average: %.2f (rounded)", average)
print(formatted2) -- Average: 95.76 (rounded)
local formatted_date = string.format("Date: %02d/%02d/%04d", 5, 7, 2023)
print(formatted_date) -- Date: 05/07/2023

字符和字节表示(string.char、string.byte)

Section titled “字符和字节表示(string.char、string.byte)”
local char_A = string.char(65) -- 'A' 的 ASCII 值
print("Character for 65:", char_A) -- 65 对应的字符: A
local str_abc = "abc"
local byte_a = string.byte(str_abc, 1) -- 'a' 的字节值
local byte_b = string.byte(str_abc, 2)
print(string.format("Byte for 'a': %d, Byte for 'b': %d", byte_a, byte_b)) -- 'a' 的字节: 97, 'b' 的字节: 98
-- 获取所有字节
for i = 1, #str_abc do
print(string.format("Byte at %d: %d", i, string.byte(str_abc, i)))
end
local s1 = "Lua"
local s2 = "Rocks"
-- 使用 .. 运算符连接
local combined = s1 .. " " .. s2 .. "!"
print("Combined string:", combined) -- 连接后的字符串: Lua Rocks!
-- 使用 # 运算符或 string.len() 获取长度
print("Length of s1:", #s1) -- s1 的长度: 3
print("Length of combined:", string.len(combined)) -- 连接后字符串的长度: 10
-- 使用 string.rep() 重复
local repeated_s1 = string.rep(s1, 3)
print("Repeated s1:", repeated_s1) -- 重复的 s1: LuaLuaLua
-- 带分隔符的重复 (Lua 5.4+)
-- local repeated_sep = string.rep(s1, 3, "-")
-- print("Repeated with sep:", repeated_sep) -- Lua-Lua-Lua(如果使用 Lua 5.4+)

关于 UTF-8 和字符串长度的重要说明:

Lua 的核心字符串库函数(如 string.len、#、string.sub)是操作字节,而不是字符。如果您处理的是 UTF-8 编码的字符串,一个字符可能占用多个字节。例如,#"你好" 很可能会返回 6(每个字符 3 个字节),而不是 2。Lua 5.3+ 包含一个 utf8 库(utf8.len、utf8.sub 等),用于正确处理 UTF-8 编码的 Unicode 字符串。在处理国际文本时,请注意这种区别。

更多资源:官方的 Lua 参考手册详细介绍了所有字符串库函数和模式匹配(pattern matching)功能。