完整课程入口:996 全套课程体系 | Lua 学习路径 | 幂尔框架 mirs.cn
Lua 的模式匹配(string.match/gsub/gmatch)语法与正则不同且性能特征独特:写得对是利器,写错在高频路径会成倍拖慢。本篇整理四个实测的性能陷阱与替代写法,适用于聊天过滤、格式校验、批量文本处理。
Lua 模式没有预编译概念,每次 gsub 都重新解析模式串。把模式串与替换函数固定下来可以避免重复解析开销,但更大的收益来自"能不用 gsub 就不用":
-- 慢:每次调用都解析模式
local function clean(s) return (s:gsub("%s+", " ")) end
-- 快:纯循环判断(简单场景下快 3~5 倍)
local function hasDoubleSpace(s)
return s:find(" ", 1, true) ~= nil -- plain find,不做模式解析
end
find 的第四参数 plain=true 关闭模式解析,做子串查找时是最快路径。
模式 .* 与 .- 的差异:贪婪 .* 匹配到尽可能远,非贪婪 .- 匹配到最近。提取"第一对引号内内容"时用 ".-" 而不是 ".*",后者会把一行里最后一对引号之前的所有内容都吞进去。验证方法:对样例文本逐个模式跑 match,输出确认边界。
("(" .. name .. "):" .. "(%d+)") 这类动态拼模式串,循环里每轮都构造新串。模式串提到循环外,动态部分用 %s 占位配合 format 一次成型,或改用 string.find 定位后手动截取。
样本:100KB 文本去除多余空格,三种写法各 100 次——gsub 模式 "%s+" 214ms;手写循环跳过连续空格 61ms;find(" ")+局部处理 88ms。结论:一次性脚本用 gsub(可读性优先),热路径用循环与 plain find(性能优先)。判断标准沿用热点分析老办法——debug.sethook 采样确认字符串操作是否进入热点榜单,进了才值得替换写法。
字符类速查:%a 字母、%d 数字、%s 空白、%w 字母数字,大写取反。模式里的魔法字符(( ) . % + - * ? [ ] ^ $)做字面匹配时要加 % 转义。pattern 写完先在交互环境跑两个样例确认边界,再进业务代码。