
1. Lua字符串模块概述Lua作为一门轻量级脚本语言其字符串处理能力在实际开发中扮演着关键角色。与C/C等语言不同Lua的字符串是内部化的interned这意味着相同内容的字符串在内存中只有一份拷贝这种设计极大优化了字符串比较和表操作的性能。字符串模块作为Lua标准库的核心组件提供了从基础操作到模式匹配的完整工具链。在Lua中字符串属于不可变immutable对象任何修改操作都会生成新的字符串实例。这种特性虽然保证了线程安全但在频繁修改场景下需要注意性能问题。标准字符串库通过string表提供所有功能使用时无需额外加载直接通过string.function()或字符串方法调用语法str:function()即可访问。提示Lua 5.3版本中字符串默认采用UTF-8编码但部分函数如len()仍按字节计数处理多字节字符时需要特别注意。2. 核心字符串操作函数详解2.1 基础字符串操作string.sub(s, i [, j])实现字符串截取功能参数i和j表示起始和结束位置包含支持负数索引从末尾倒数。例如local str Hello World print(string.sub(str, 2, 5)) -- 输出 ello print(str:sub(-5, -1)) -- 方法调用语法输出 Worldstring.rep(s, n)字符串重复拼接常用于生成测试数据或格式对齐print(string.rep(-, 30)) -- 输出30个连字符string.reverse(s)反转字符串字符顺序注意多字节字符场景print(string.reverse(Lua)) -- 输出 auL2.2 大小写转换与格式化string.lower(s) / string.upper(s)全字母大小写转换支持Unicode字符print(string.upper(München)) -- 输出 MÜNCHENstring.format(fmt, ...)Lua版的sprintf支持以下格式说明符%d十进制整数%f浮点数%s字符串%q带引号和转义的字符串安全拼接SQL时特别有用示例print(string.format(PI%.2f, Hex%X, math.pi, 255)) -- 输出 PI3.14, HexFF3. 字符串查找与模式匹配3.1 基础查找函数string.find(s, pattern [, init [, plain]])返回匹配起始和结束位置未找到返回nillocal start, finish string.find(Lua is great, is) print(start, finish) -- 输出 5 6string.match(s, pattern [, init])提取匹配的子串适合捕获组提取local day string.match(Today is 2023-07-20, %d-%d-%d) print(day) -- 输出 2023-07-203.2 高级模式匹配Lua的模式匹配不是完整正则表达式但支持以下元字符.任意字符%a字母%d数字%s空白字符%x十六进制数字[set]自定义字符集1次或多次*0次或多次-0次或多次非贪婪模式?0次或1次示例提取HTML标签内容local html divContent/div local content html:match(%w(.-)/%w) print(content) -- 输出 Content4. 字符串修改与转换4.1 字符串替换string.gsub(s, pattern, repl [, n])全局替换返回新字符串和替换次数local new string.gsub(Lua Lua Lua, Lua, Moon, 2) print(new) -- 输出 Moon Moon Lua4.2 字符串分割与连接Lua标准库未直接提供split函数可通过gmatch实现function split(s, delimiter) local result {} for match in (s..delimiter):gmatch((.-)..delimiter) do table.insert(result, match) end return result end local parts split(a,b,c, ,) -- parts {a, b, c}字符串连接推荐使用table.concat提升性能local chunks {Lua, is, fast} print(table.concat(chunks, )) -- 输出 Lua is fast5. 编码转换与二进制处理5.1 字符与编码转换string.byte(s [, i [, j]])返回字符的ASCII/Unicode码print(string.byte(ABC)) -- 输出 65string.char(...)将整数转换为对应字符print(string.char(65, 66, 67)) -- 输出 ABC5.2 二进制数据处理处理二进制数据时常用格式化输出local data {0x48, 0x65, 0x6C, 0x6C, 0x6F} local binstr string.char(table.unpack(data)) print(binstr) -- 输出 Hello6. 性能优化实践6.1 字符串拼接优化避免在循环中使用..拼接-- 错误示范产生大量临时字符串 local result for i1,10000 do result result .. tostring(i) end -- 正确做法使用table缓存 local t {} for i1,10000 do t[#t1] tostring(i) end result table.concat(t)6.2 模式匹配性能复杂模式匹配可预编译local pattern ^%d%s*%s*%d$ local compiled {} function compiled.match(s) return string.match(s, pattern) end -- 后续重复使用compiled.match()7. 实际应用案例7.1 配置文件解析解析INI格式配置文件local config {} for line in io.lines(config.ini) do local key, val line:match(^%s*([%w_])%s*%s*(.-)%s*$) if key then config[key] val end end7.2 日志分析提取Nginx日志中的IP和状态码local log 192.168.1.1 - - [20/Jul/2023:10:12:33 0800] GET /api HTTP/1.1 200 1234 local ip, status log:match(^(%d%.%d%.%d%.%d).*%%s(%d)%s%d$) print(ip, status) -- 输出 192.168.1.1 2007.3 数据验证验证邮箱格式function is_valid_email(email) return email:match(^[%w%.%-][%w%.%-]%.%a%a$) ~ nil end8. 常见问题与解决方案8.1 多字节字符处理使用第三方库如luautf8处理UTF-8字符串local utf8 require(lua-utf8) print(utf8.len(中文)) -- 正确输出28.2 内存泄漏排查长时间运行的字符串操作可能导致内存增长-- 使用collectgarbage()监控内存 local start_mem collectgarbage(count) -- 执行字符串操作... print(collectgarbage(count) - start_mem)8.3 模式匹配特殊字符转义特殊字符的函数实现function escape_pattern(s) return s:gsub(([%%%.%[%]%(%)%%-%?%^%$]), %%%1) end在游戏开发中处理玩家输入时我发现string.gsub的替换函数形式特别有用。比如实现聊天敏感词过滤系统local sensitive_words {bad, word} local function censor(word) return string.rep(*, #word) end function filter_message(msg) for _, word in ipairs(sensitive_words) do msg msg:gsub(word, censor) end return msg end对于需要高性能字符串处理的场景如网络协议解析建议将关键函数用C模块实现。我曾在一个MMO服务器项目中将热路径上的字符串处理函数改用C实现使整体性能提升了约40%。