Lua 小白入门教程Lua 小白入门教程
首页
基础教程
实战进阶
编程指南
首页
基础教程
实战进阶
编程指南
  • 基础教程

    • 📚 基础教程
    • 第1章 - Lua 是什么?
    • 第2章 - 环境搭建
    • 第3章 - 变量与数据类型
    • 第4章 - 运算符与表达式
    • 第5章 - 流程控制
    • 第6章 - 函数
    • 第7章 - Table(表)
    • 第8章 - 字符串与模式匹配

第8章 - 字符串与模式匹配

嗨,朋友!我是长安。

这一章我们来聊聊 Lua 的字符串处理。Lua 的字符串库虽然没有 Java 那么丰富,但有一套独特的模式匹配系统,比正则表达式更轻量,在很多场景下够用了。

📖 字符串基础

-- 字符串定义
local s1 = "Hello"           -- 双引号
local s2 = 'World'           -- 单引号
local s3 = [[               
这是多行字符串
可以直接换行
不需要转义符
]]

-- 转义字符(和 Java 一样)
local s4 = "Hello\nWorld"    -- 换行
local s5 = "Tab\there"       -- 制表符
local s6 = "引号: \"Hi\""    -- 转义引号

-- 字符串长度
print(#"Hello")              -- 5
print(string.len("Hello"))   -- 5

🔧 string 库常用函数

大小写转换

local s = "Hello World"
print(string.upper(s))       -- HELLO WORLD
print(string.lower(s))       -- hello world
// Java 等价
"Hello World".toUpperCase();   // HELLO WORLD
"Hello World".toLowerCase();   // hello world

子串截取

local s = "Hello World"
print(string.sub(s, 1, 5))   -- Hello(从位置1到5)
print(string.sub(s, 7))      -- World(从位置7到末尾)
print(string.sub(s, -5))     -- World(倒数5个字符)
// Java 等价(注意 Java 索引从 0 开始)
"Hello World".substring(0, 5);   // Hello
"Hello World".substring(6);      // World

注意

string.sub 的索引从 1 开始,和 Table 一样。Java 的 substring 从 0 开始。

查找

local s = "Hello World"

-- string.find 返回起始和结束位置
local start, finish = string.find(s, "World")
print(start, finish)          -- 7  11

-- 找不到返回 nil
local result = string.find(s, "Lua")
print(result)                 -- nil
// Java 等价
"Hello World".indexOf("World");  // 6(Java 从 0 开始)
"Hello World".indexOf("Lua");    // -1

替换

local s = "Hello World World"

-- string.gsub(源字符串, 模式, 替换值)
local result, count = string.gsub(s, "World", "Lua")
print(result)                 -- Hello Lua Lua
print(count)                  -- 2(替换了2次)

-- 限制替换次数
local result2 = string.gsub(s, "World", "Lua", 1)
print(result2)                -- Hello Lua World(只替换1次)
// Java 等价
"Hello World World".replaceAll("World", "Lua");   // Hello Lua Lua
"Hello World World".replaceFirst("World", "Lua");  // Hello Lua World

格式化

-- string.format 类似 Java 的 String.format / C 的 printf
local name = "长安"
local age = 25
local score = 98.5

print(string.format("姓名: %s, 年龄: %d, 分数: %.1f", name, age, score))
-- 姓名: 长安, 年龄: 25, 分数: 98.5
格式符说明示例
%s字符串"hello"
%d整数42
%f浮点数3.14
%.2f保留2位小数3.14
%x十六进制ff
%02d补零到2位05
%%输出 % 本身%

重复和反转

-- 重复
print(string.rep("Ha", 3))       -- HaHaHa
print(string.rep("-", 20))       -- --------------------

-- 反转
print(string.reverse("Hello"))   -- olleH

-- 字节码
print(string.byte("A"))          -- 65
print(string.char(65))           -- A

🎯 模式匹配

Lua 的模式匹配比正则表达式更轻量。不支持完整的正则,但对于大多数场景够用了。

模式字符

字符说明正则等价
.任意字符.
%a字母[a-zA-Z]
%d数字[0-9]
%l小写字母[a-z]
%u大写字母[A-Z]
%w字母和数字[a-zA-Z0-9]
%s空白字符\s
%p标点符号[[:punct:]]
%A非字母[^a-zA-Z]
%D非数字[^0-9]

量词

量词说明正则等价
*0 个或多个(贪婪)*
+1 个或多个(贪婪)+
-0 个或多个(非贪婪)*?
?0 个或 1 个?

模式匹配示例

local s = "Today is 2024-01-15, temperature is 25.5°C"

-- 查找日期
local year, month, day = string.match(s, "(%d+)-(%d+)-(%d+)")
print(year, month, day)     -- 2024  01  15

-- 查找所有数字
for num in string.gmatch(s, "%d+%.?%d*") do
    print(num)
end
-- 2024
-- 01
-- 15
-- 25.5

-- 提取邮箱(简单版)
local email = "联系我: zhangsan@example.com 谢谢"
local addr = string.match(email, "%w+@%w+%.%w+")
print(addr)                 -- zhangsan@example.com
// Java 正则等价
Pattern pattern = Pattern.compile("(\\d+)-(\\d+)-(\\d+)");
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
    System.out.println(matcher.group(1));  // 2024
    System.out.println(matcher.group(2));  // 01
    System.out.println(matcher.group(3));  // 15
}

string.gmatch — 全局匹配迭代

-- 遍历所有单词
local s = "Hello World Lua Java"
for word in string.gmatch(s, "%a+") do
    print(word)
end
-- Hello
-- World
-- Lua
-- Java

-- 解析键值对
local params = "name=长安&age=25&job=developer"
for key, value in string.gmatch(params, "(%w+)=([^&]+)") do
    print(key .. " -> " .. value)
end
-- name -> 长安
-- age -> 25
-- job -> developer

📊 字符串方法速查表

LuaJava说明
string.len(s) 或 #ss.length()长度
string.sub(s, i, j)s.substring(i-1, j)截取
string.find(s, pattern)s.indexOf(str)查找
string.gsub(s, p, r)s.replaceAll(p, r)替换
string.match(s, p)Pattern/Matcher模式匹配
string.gmatch(s, p)Pattern/Matcher全局匹配
string.format(fmt, ...)String.format(fmt, ...)格式化
string.upper(s)s.toUpperCase()转大写
string.lower(s)s.toLowerCase()转小写
string.rep(s, n)s.repeat(n)重复
string.reverse(s)new StringBuilder(s).reverse()反转

💡 面向对象风格调用

Lua 字符串支持用冒号语法调用 string 库的方法:

local s = "Hello World"

-- 以下两种写法等价
print(string.upper(s))        -- HELLO WORLD
print(s:upper())              -- HELLO WORLD

print(string.sub(s, 1, 5))   -- Hello
print(s:sub(1, 5))            -- Hello

print(s:find("World"))        -- 7  11
print(s:gsub("World", "Lua")) -- Hello Lua  1

推荐

用冒号风格 s:upper() 更简洁,类似 Java 的 s.toUpperCase()。

📝 小结

  • Lua 字符串是不可变的(和 Java 的 String 一样)
  • string 库提供了丰富的字符串操作函数
  • 模式匹配用 %d、%a、%w 等而不是正则的 \d、[a-zA-Z]
  • 推荐使用冒号风格调用:s:upper()、s:find()
  • string.format 和 Java 的 String.format 非常相似

➡️ 下一步

恭喜你!基础教程全部学完了!🎉 接下来可以进入 实战进阶 部分,学习模块化、文件操作、面向对象,以及最重要的——如何在 SpringBoot 项目中使用 Lua!

💪 练习题

  1. 把字符串 "hello world" 转成 "Hello World"(首字母大写)。
  2. 从字符串 "2024-01-15 14:30:00" 中提取年、月、日、时、分、秒。
  3. 写一个函数,统计字符串中数字的个数。
  4. 用 string.gsub 把字符串中所有空格替换成下划线。

答案提示

  1. s:sub(1,1):upper() .. s:sub(2) 或使用 gsub + 模式匹配
  2. string.match(s, "(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+)")
  3. local _, count = s:gsub("%d", "") 利用 gsub 第二个返回值
  4. s:gsub("%s", "_")
最近更新: 2026/2/27 17:54
Contributors: 王长安
Prev
第7章 - Table(表)