字符串 #

一、字符串创建 #

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 字符串的全面操作:

  1. 字符串创建:单引号、双引号、长字符串
  2. 基本操作:长度、连接、比较
  3. 字符串函数:大小写、子串、查找、替换
  4. 格式化:string.format 的各种用法
  5. 模式匹配:Lua 强大的模式匹配功能
  6. 实用函数:分割、修剪、编码等

字符串操作是 Lua 编程中最常用的功能之一。下一章,我们将学习运算符。

最后更新:2026-03-27