标准库详解
Lua标准库详解:字符串库、表库、数学库、IO库、操作系统库与调试库。
1. 字符串库(string)
1.1 基本操作
-- 字符串长度
local s = "Hello, Lua!"
print(string.len(s)) -- 11
print(#s) -- 11(推荐写法)
-- 字符串拼接
local name = "World"
local greeting = "Hello, " .. name .. "!"
-- 大小写转换
print(string.upper("hello")) -- "HELLO"
print(string.lower("WORLD")) -- "world"
-- 子串
print(string.sub("Hello World", 1, 5)) -- "Hello"
print(string.sub("Hello World", 7)) -- "World"
print(string.sub("Hello World", -5)) -- "orld"(负索引从末尾计)
-- 重复
print(string.rep("Ha", 3)) -- "HaHaHa"
-- 反转
print(string.reverse("abc")) -- "cba"
1.2 查找与匹配
-- find: 查找子串位置
local s = "Hello, Lua World!"
local start, finish = string.find(s, "Lua")
print(start, finish) -- 8 10
-- 支持模式匹配
local start2 = string.find(s, "%a+") -- 查找第一个单词
print(start2) -- 1
-- match: 匹配并返回
local date = "2026-06-13"
local y, m, d = string.match(date, "(%d+)-(%d+)-(%d+)")
print(y, m, d) -- 2026 06 13
-- gmatch: 全局匹配迭代器
local text = "Hello World, Hello Lua"
for word in string.gmatch(text, "%a+") do
print(word) -- Hello, World, Hello, Lua
end
-- gsub: 全局替换
local result = string.gsub("hello world", "l", "L")
print(result) -- "heLLo worLd"
-- 限制替换次数
local result2 = string.gsub("hello world", "l", "L", 1)
print(result2) -- "heLlo world"
-- 使用捕获组
local result3 = string.gsub("2026-06-13", "(%d+)-(%d+)-(%d+)", "%3/%2/%1")
print(result3) -- "13/06/2026"
1.3 模式匹配语法
-- 字符类
-- %a 字母
-- %d 数字
-- %l 小写字母
-- %u 大写字母
-- %w 字母和数字
-- %s 空白字符
-- %p 标点符号
-- %c 控制字符
-- 大写版本表示补集:如%A表示非字母
-- 量词
-- + 1次或多次(贪婪)
-- * 0次或多次(贪婪)
-- - 0次或多次(非贪婪)
-- ? 0次或1次
-- 实用模式
local email = "user@example.com"
local user, domain = string.match(email, "([%w%.%+%-]+)@([%w%.%-]+)")
print(user, domain) -- user example.com
local url = "https://example.com:8080/path"
local protocol, host, port, path = string.match(url, "^(%w+)://([%w%.%-]+):?(%d*)(.*)")
print(protocol, host, port, path)
1.4 格式化
-- string.format: 类似C的printf
print(string.format("Hello, %s!", "World")) -- Hello, World!
print(string.format("Number: %d", 42)) -- Number: 42
print(string.format("Float: %.2f", 3.14159)) -- Float: 3.14
print(string.format("Hex: %x", 255)) -- Hex: ff
print(string.format("Oct: %o", 8)) -- Oct: 10
print(string.format("Padding: %05d", 42)) -- Padding: 00042
print(string.format("Left: %-10s|", "hi")) -- Left: hi |
2. 表库(table)
2.1 插入与删除
local fruits = {"apple", "banana", "cherry"}
-- table.insert: 插入元素
table.insert(fruits, "date") -- 末尾插入
table.insert(fruits, 2, "blueberry") -- 在位置2插入
-- {"apple", "blueberry", "banana", "cherry", "date"}
-- table.remove: 删除元素
local removed = table.remove(fruits) -- 删除并返回末尾元素 "date"
local removed2 = table.remove(fruits, 1) -- 删除并返回位置1 "apple"
-- {"blueberry", "banana", "cherry"}
-- table.sort: 排序
local nums = {3, 1, 4, 1, 5, 9, 2, 6}
table.sort(nums)
-- {1, 1, 2, 3, 4, 5, 6, 9}
-- 自定义排序
local people = {
{name = "Alice", age = 25},
{name = "Bob", age = 30},
{name = "Charlie", age = 20},
}
table.sort(people, function(a, b) return a.age < b.age end)
2.2 其他表操作
-- table.concat: 连接数组元素
local parts = {"Hello", "World", "Lua"}
print(table.concat(parts, ", ")) -- "Hello, World, Lua"
-- table.maxn: 最大正整数索引(Lua 5.1)
-- Lua 5.3+ 使用 # 操作符
-- 表的深拷贝
function deep_copy(orig)
local copy
if type(orig) == "table" then
copy = {}
for k, v in pairs(orig) do
copy[deep_copy(k)] = deep_copy(v)
end
setmetatable(copy, deep_copy(getmetatable(orig)))
else
copy = orig
end
return copy
end
-- 表合并
function merge_tables(...)
local result = {}
for _, t in ipairs({...}) do
for k, v in pairs(t) do
result[k] = v
end
end
return result
end
local merged = merge_tables({a = 1, b = 2}, {b = 3, c = 4})
-- {a = 1, b = 3, c = 4}
3. 数学库(math)
3.1 基本数学函数
-- 常量
print(math.pi) -- 3.1415926535898
print(math.huge) -- inf
print(math.maxinteger) -- 最大整数
print(math.mininteger) -- 最小整数
-- 取整
print(math.floor(3.7)) -- 3(向下取整)
print(math.ceil(3.2)) -- 4(向上取整)
print(math.abs(-5)) -- 5(绝对值)
-- 最值
print(math.max(1, 5, 3)) -- 5
print(math.min(1, 5, 3)) -- 1
-- 幂与对数
print(math.sqrt(16)) -- 4
print(math.pow(2, 10)) -- 1024
print(math.exp(1)) -- 2.718281828459
print(math.log(100)) -- 4.6051701859881
print(math.log(100, 10)) -- 2(以10为底)
-- 三角函数(弧度制)
print(math.sin(math.pi / 2)) -- 1
print(math.cos(0)) -- 1
print(math.tan(math.pi / 4)) -- 1
-- 角度弧度转换
print(math.rad(180)) -- 3.1415926535898
print(math.deg(math.pi)) -- 180
3.2 随机数
-- 设置随机种子
math.randomseed(os.time())
-- 生成随机数
print(math.random()) -- [0, 1) 随机浮点数
print(math.random(10)) -- [1, 10] 随机整数
print(math.random(5, 10)) -- [5, 10] 随机整数
-- 随机选择
function random_choice(t)
return t[math.random(#t)]
end
local colors = {"red", "green", "blue"}
print(random_choice(colors))
-- 洗牌算法
function shuffle(t)
for i = #t, 2, -1 do
local j = math.random(i)
t[i], t[j] = t[j], t[i]
end
return t
end
4. IO 库
4.1 文件操作
-- 打开文件
local file = io.open("test.txt", "r") -- r/w/a/r+/w+/a+
if file then
-- 读取整个文件
local content = file:read("*a")
print(content)
-- 逐行读取
file:seek("set") -- 回到文件开头
for line in file:lines() do
print(line)
end
file:close()
end
-- 写入文件
local outfile = io.open("output.txt", "w")
if outfile then
outfile:write("Hello, Lua!\n")
outfile:write("Second line\n")
outfile:close()
end
-- 追加写入
local appendfile = io.open("output.txt", "a")
if appendfile then
appendfile:write("Appended line\n")
appendfile:close()
end
4.2 简化 IO
-- io.read: 从标准输入读取
-- io.write: 写到标准输出
-- 临时文件
local tmp = io.tmpfile()
tmp:write("temporary data")
tmp:seek("set")
print(tmp:read("*a")) -- "temporary data"
tmp:close()
-- 文件存在检查
function file_exists(path)
local f = io.open(path, "r")
if f then
f:close()
return true
end
return false
end
5. 操作系统库(os)
5.1 时间与日期
-- 当前时间戳
print(os.time()) -- 如 1781365236
-- 格式化日期
print(os.date()) -- "06/13/26 14:30:36"
print(os.date("%Y-%m-%d")) -- "2026-06-13"
print(os.date("%H:%M:%S")) -- "14:30:36"
-- 常用格式符
-- %Y 四位年份 %m 月份(01-12) %d 日(01-31)
-- %H 小时(00-23) %M 分钟(00-59) %S 秒(00-59)
-- %A 星期名 %B 月份名 %w 星期(0-6)
-- 从时间戳构造日期
local timestamp = os.time({year = 2026, month = 6, day = 13})
print(os.date("%Y-%m-%d", timestamp)) -- "2026-06-13"
-- 时间差计算
local t1 = os.time()
-- ... 执行一些操作 ...
local t2 = os.time()
print(string.format("耗时: %.2f秒", os.difftime(t2, t1)))
5.2 系统操作
-- 执行系统命令
os.execute("mkdir -p temp")
local result = os.execute("ls -la")
print("命令结果:", result)
-- 获取环境变量
print(os.getenv("HOME")) -- 用户主目录
print(os.getenv("PATH")) -- 系统PATH
print(os.getenv("SHELL")) -- 当前Shell
-- 退出程序
-- os.exit(0) -- 正常退出
-- os.exit(1) -- 异常退出
-- 重命名和删除文件
os.rename("old.txt", "new.txt")
os.remove("unwanted.txt")
6. 调试库(debug)
6.1 调试信息
-- 获取调用栈
function foo()
function bar()
print(debug.traceback("调用栈:"))
end
bar()
end
foo()
-- 获取函数信息
local info = debug.getinfo(1) -- 当前函数
print("函数名:", info.name)
print("源文件:", info.source)
print("行号:", info.currentline)
print("类型:", info.what)
-- 获取局部变量
function show_locals()
local x = 10
local y = "hello"
local i = 1
while true do
local name, value = debug.getlocal(1, i)
if not name then break end
print(name, "=", value)
i = i + 1
end
end
show_locals()
7. 常见问题与解决方案
7.1 字符串索引从1开始
-- Lua字符串和数组索引从1开始
local s = "Hello"
print(string.sub(s, 1, 1)) -- "H"(不是s[0])
print(s:sub(1, 3)) -- "Hel"(方法调用语法)
7.2 模式匹配不是正则表达式
-- Lua的模式匹配比正则简单,但有差异
-- 用 % 转义而非 \
-- 不支持 | (或)、{n,m} 等语法
-- 非贪婪用 - 而非 *?
-- 匹配IP地址
local ip = "192.168.1.1"
local a, b, c, d = ip:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
print(a, b, c, d) -- 192 168 1 1
7.3 table.sort 只对数组部分有效
-- table.sort 只排序连续整数索引部分
local mixed = {3, 1, 2, key = "value"}
table.sort(mixed) -- 只排序 3, 1, 2
8. 总结与最佳实践
8.1 标准库使用建议
- 字符串操作:使用
:方法调用语法(s:sub()优于string.sub(s)) - 表操作:注意数组部分和哈希部分是独立的
- 随机数:始终设置
math.randomseed - 文件操作:始终检查
io.open返回值,使用pcall处理异常 - 模式匹配:Lua模式不是正则,注意
%转义
8.2 性能建议
- 字符串拼接使用
table.concat而非..循环拼接 - 预编译模式:
string.format比..拼接更高效 - 大表操作注意
#操作符只计算数组部分 - 使用
local缓存库函数引用:local sub = string.sub