字符串 #
一、字符串创建 #
1.1 字符串字面量 #
lua
-- 单引号
local s1 = 'Hello'
-- 双引号
local s2 = "World"
-- 单双引号无区别
print('Hello' == "Hello") -- true
1.2 长字符串 #
lua
-- [[ ]] 定义多行字符串
local s1 = [[
第一行
第二行
第三行
]]
-- 带等号的长字符串(避免嵌套冲突)
local s2 = [==[
包含 [[ 和 ]] 的字符串
]==]
local s3 = [=[
这里的 [[ 和 ]] 不会冲突
]=]
1.3 转义字符 #
lua
-- 常用转义字符
print("换行:\n") -- 换行
print("制表符:\t") -- 制表符
print("回车:\r") -- 回车
print("引号:\"") -- 双引号
print("单引号:\'") -- 单引号
print("反斜杠:\\") -- 反斜杠
-- 数字转义
print("\65") -- A(ASCII 码)
print("\x41") -- A(十六进制)
print("\u{4E2D}") -- 中(Unicode)
二、字符串基本操作 #
2.1 字符串长度 #
lua
local s = "Hello, Lua!"
-- 使用 # 操作符
print(#s) -- 12
-- 使用 string.len
print(string.len(s)) -- 12
-- 中文字符串长度(UTF-8)
local chinese = "你好"
print(#chinese) -- 6(每个中文 3 字节)
2.2 字符串连接 #
lua
-- 使用 .. 操作符
local s1 = "Hello" .. " " .. "World"
-- 连接数字(自动转换)
local s2 = "数字:" .. 42
-- 多行连接
local s3 = "第一行\n" ..
"第二行\n" ..
"第三行"
-- 高效连接大量字符串
local parts = {"a", "b", "c", "d"}
local s4 = table.concat(parts, ",") -- "a,b,c,d"
2.3 字符串比较 #
lua
-- 相等比较
print("hello" == "hello") -- true
print("hello" == "Hello") -- false
-- 大小比较(字典序)
print("a" < "b") -- true
print("a" < "A") -- false(ASCII 码比较)
-- 不区分大小写比较
local function equals_ignore_case(a, b)
return string.lower(a) == string.lower(b)
end
print(equals_ignore_case("Hello", "HELLO")) -- true
三、字符串函数 #
3.1 大小写转换 #
lua
local s = "Hello, Lua!"
print(string.upper(s)) -- HELLO, LUA!
print(string.lower(s)) -- hello, lua!
-- 首字母大写
local function capitalize(s)
return string.upper(string.sub(s, 1, 1)) .. string.lower(string.sub(s, 2))
end
print(capitalize("hello")) -- Hello
3.2 子串操作 #
lua
local s = "Hello, Lua!"
-- string.sub(s, start, end)
print(string.sub(s, 1, 5)) -- Hello
print(string.sub(s, 8)) -- Lua!
print(string.sub(s, -4, -1)) -- Lua!
-- 索引从 1 开始,-1 表示最后一个字符
print(string.sub(s, -5)) -- Lua!
-- 获取单个字符
print(string.sub(s, 1, 1)) -- H
3.3 查找与匹配 #
lua
local s = "Hello, Lua World!"
-- string.find 查找位置
local start, finish = string.find(s, "Lua")
print(start, finish) -- 8 10
-- 从指定位置开始查找
local start2 = string.find(s, "o", 5)
print(start2) -- 16
-- 使用模式匹配
local date = "2024-03-27"
local y, m, d = string.match(date, "(%d+)-(%d+)-(%d+)")
print(y, m, d) -- 2024 03 27
3.4 替换 #
lua
local s = "Hello, Lua!"
-- string.gsub 替换
local new_s, count = string.gsub(s, "Lua", "World")
print(new_s) -- Hello, World!
print(count) -- 1(替换次数)
-- 替换所有匹配
local s2 = "a1b2c3"
local new_s2 = string.gsub(s2, "%d", "X")
print(new_s2) -- aXbXcX
-- 使用函数替换
local s3 = "hello world"
local new_s3 = string.gsub(s3, "%a", function(c)
return string.upper(c)
end)
print(new_s3) -- HELLO WORLD
3.5 重复与反转 #
lua
-- string.rep 重复
print(string.rep("ab", 3)) -- ababab
print(string.rep("-", 10)) -- ----------
-- 字符串反转
local function reverse(s)
return string.reverse(s)
end
print(string.reverse("hello")) -- olleh
3.6 字符与ASCII码 #
lua
-- string.byte 获取字节
print(string.byte("A")) -- 65
print(string.byte("ABC", 2)) -- 66
-- string.char 从字节创建字符
print(string.char(65)) -- A
print(string.char(65, 66, 67)) -- ABC
四、字符串格式化 #
4.1 string.format #
lua
-- 基本格式化
print(string.format("Hello, %s!", "Lua")) -- Hello, Lua!
-- 数字格式化
print(string.format("整数:%d", 42)) -- 整数:42
print(string.format("浮点数:%.2f", 3.14159)) -- 浮点数:3.14
print(string.format("科学计数:%e", 1000)) -- 科学计数:1.000000e+03
-- 宽度和对齐
print(string.format("|%10s|", "hello")) -- | hello|
print(string.format("|%-10s|", "hello")) -- |hello |
print(string.format("|%05d|", 42)) -- |00042|
4.2 格式化占位符 #
| 占位符 | 描述 |
|---|---|
| %s | 字符串 |
| %d | 整数 |
| %f | 浮点数 |
| %x | 十六进制整数 |
| %o | 八进制整数 |
| %e | 科学计数法 |
| %c | 字符(ASCII 码) |
| %q | 安全引用字符串 |
| %% | 百分号 |
lua
-- 示例
print(string.format("字符串:%s", "hello"))
print(string.format("整数:%d", 42))
print(string.format("十六进制:%x", 255)) -- ff
print(string.format("八进制:%o", 8)) -- 10
print(string.format("字符:%c", 65)) -- A
print(string.format("引用:%q", "有\"引号\"")) -- "有\"引号\""
五、模式匹配 #
5.1 基本模式 #
lua
-- . 任意字符
print(string.match("hello", ".")) -- h
-- %a 字母
print(string.match("hello123", "%a+")) -- hello
-- %d 数字
print(string.match("hello123", "%d+")) -- 123
-- %w 字母数字
print(string.match("hello_123", "%w+")) -- hello_123
-- %s 空白字符
print(string.match("hello world", "%s")) -- (空格)
-- %p 标点符号
print(string.match("hello,world", "%p")) -- ,
-- %c 控制字符
-- %l 小写字母
-- %u 大写字母
-- %x 十六进制数字
5.2 模式字符类 #
| 字符类 | 描述 |
|---|---|
| . | 任意字符 |
| %a | 字母 |
| %d | 数字 |
| %l | 小写字母 |
| %u | 大写字母 |
| %w | 字母和数字 |
| %s | 空白字符 |
| %p | 标点符号 |
| %c | 控制字符 |
| %x | 十六进制数字 |
| %z | 零字符(Lua 5.1) |
| %b | 平衡匹配 |
5.3 模式修饰符 #
lua
-- + 一个或多个
print(string.match("hello123", "%d+")) -- 123
-- * 零个或多个
print(string.match("hello", "%d*")) -- (空字符串)
-- - 零个或多个(最短匹配)
local s = "<a><b>"
print(string.match(s, "<.*>")) -- <a><b>(贪婪)
print(string.match(s, "<.->")) -- <a>(非贪婪)
-- ? 可选(零个或一个)
print(string.match("color", "colou?r")) -- color
print(string.match("colour", "colou?r")) -- colour
5.4 捕获 #
lua
-- 使用 () 捕获
local s = "Hello, Lua!"
local hello, lua = string.match(s, "(%w+), (%w+)!")
print(hello, lua) -- Hello Lua
-- 捕获日期
local date = "2024-03-27"
local y, m, d = string.match(date, "(%d+)-(%d+)-(%d+)")
print(y, m, d) -- 2024 03 27
-- 捕获邮箱
local email = "user@example.com"
local user, domain = string.match(email, "([^@]+)@(.+)")
print(user, domain) -- user example.com
-- 捕获引用
local s = "hello world"
print(string.match(s, "(.+) %1")) -- nil
print(string.match(s, "(%w+) %1")) -- nil
-- 正确的重复单词匹配
local s2 = "hello hello"
print(string.match(s2, "(%w+) %1")) -- hello hello
5.5 常用模式示例 #
lua
-- 验证邮箱
local function is_valid_email(email)
return string.match(email, "^[%w%.%-]+@[%w%.%-]+%.[%a]+$") ~= nil
end
-- 验证手机号(中国大陆)
local function is_valid_phone(phone)
return string.match(phone, "^1[3-9]%d%d%d%d%d%d%d%d%d$") ~= nil
end
-- 提取 URL
local function parse_url(url)
local protocol, host, port, path = string.match(url, "^(%w+)://([^:/]+):?(%d*)(.*)$")
return {
protocol = protocol,
host = host,
port = port ~= "" and tonumber(port) or nil,
path = path ~= "" and path or "/"
}
end
-- 移除 HTML 标签
local function strip_html(html)
return string.gsub(html, "<[^>]+>", "")
end
六、字符串遍历 #
6.1 string.gmatch #
lua
-- 遍历所有匹配
local s = "hello world from lua"
for word in string.gmatch(s, "%a+") do
print(word)
end
-- 输出:hello, world, from, lua
-- 提取所有数字
local s2 = "a1b23c456"
for num in string.gmatch(s2, "%d+") do
print(num)
end
-- 输出:1, 23, 456
6.2 字符遍历 #
lua
-- 遍历每个字符
local s = "hello"
for i = 1, #s do
local c = string.sub(s, i, i)
print(i, c, string.byte(c))
end
-- 使用 UTF-8 库遍历(Lua 5.3+)
local utf8 = require("utf8")
local chinese = "你好世界"
for p, c in utf8.codes(chinese) do
print(p, c, utf8.char(c))
end
七、字符串分割 #
7.1 分割函数 #
lua
-- 基本分割
local function split(s, sep)
sep = sep or "%s"
local result = {}
for part in string.gmatch(s, "([^" .. sep .. "]+)") do
table.insert(result, part)
end
return result
end
local parts = split("a,b,c", ",")
-- {"a", "b", "c"}
-- 更健壮的分割
local function split2(s, sep)
sep = sep or " "
local result = {}
local pattern = string.format("([^%s]*)%s?", sep, sep)
for part in string.gmatch(s, pattern) do
table.insert(result, part)
end
return result
end
八、字符串修剪 #
8.1 去除空白 #
lua
-- 去除两端空白
local function trim(s)
return string.match(s, "^%s*(.-)%s*$")
end
print("[" .. trim(" hello ") .. "]") -- [hello]
-- 去除左端空白
local function ltrim(s)
return string.match(s, "^%s*(.+)")
end
-- 去除右端空白
local function rtrim(s)
return string.match(s, "(.-)%s*$")
end
九、实用函数 #
9.1 字符串工具 #
lua
-- 检查是否以某字符串开头
local function starts_with(s, prefix)
return string.sub(s, 1, #prefix) == prefix
end
-- 检查是否以某字符串结尾
local function ends_with(s, suffix)
return string.sub(s, -#suffix) == suffix
end
-- 检查是否包含
local function contains(s, pattern)
return string.find(s, pattern, 1, true) ~= nil
end
-- 填充字符串
local function pad_left(s, len, char)
char = char or " "
return string.rep(char, len - #s) .. s
end
local function pad_right(s, len, char)
char = char or " "
return s .. string.rep(char, len - #s)
end
9.2 编码解码 #
lua
-- URL 编码
local function url_encode(s)
s = string.gsub(s, "([^%w%.%- ])", function(c)
return string.format("%%%02X", string.byte(c))
end)
return string.gsub(s, " ", "+")
end
-- URL 解码
local function url_decode(s)
s = string.gsub(s, "+", " ")
s = string.gsub(s, "%%(%x%x)", function(hex)
return string.char(tonumber(hex, 16))
end)
return s
end
-- Base64 编码(简化版)
local b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
local function base64_encode(data)
return ((data:gsub('.', function(x)
local r, b = '', x:byte()
for i = 8, 1, -1 do r = r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
return r;
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
if (#x < 6) then return '' end
local c = 0
for i = 1, 6 do c = c + (x:sub(i, i) == '1' and 2^(6 - i) or 0) end
return b64chars:sub(c + 1, c + 1)
end)..({ '', '==', '=' })[#data % 3 + 1])
end
十、总结 #
本章介绍了 Lua 字符串的全面操作:
- 字符串创建:单引号、双引号、长字符串
- 基本操作:长度、连接、比较
- 字符串函数:大小写、子串、查找、替换
- 格式化:string.format 的各种用法
- 模式匹配:Lua 强大的模式匹配功能
- 实用函数:分割、修剪、编码等
字符串操作是 Lua 编程中最常用的功能之一。下一章,我们将学习运算符。
最后更新:2026-03-27