Lua中string.find匹配含连字符子串失败的解决方法求助
Lua string.find 子串匹配问题解决办法
我在用Lua开发Factorio模组时碰到个问题:string.find没法正确匹配同时包含连字符的子串——单独搜-mining-或-drone没问题,但搜mining-drone就匹配不到。测试代码如下:
local str = "copper-ore-mining-drone-10" local sub = "mining-drone" print(str:find(sub))
我怀疑string.find把连字符当成了模式语法的一部分,但查官方文档没找到明确说明,试着转义连字符还报了"invalid escape sequence"错误。因为子串是外部输入的,想知道怎么自动转义解决这个问题?
核心原因与解决方法
Lua的string.find默认会把第二个参数当作模式匹配串处理,而非纯字面量。虽然连字符本身在模式串里(不在字符集[]内时)没有特殊意义,但如果外部输入的子串包含其他模式特殊字符(比如^$%.()[*+?等),就会导致匹配失败。
方法1:开启纯字面量搜索(最简便)
string.find支持第四个可选参数plain,设为true后,第二个参数会被当作普通子串处理,完全跳过模式匹配逻辑,不需要转义任何字符:
local str = "copper-ore-mining-drone-10" local sub = "mining-drone" -- 第三个参数是搜索起始位置,这里填1表示从开头搜 print(str:find(sub, 1, true)) -- 输出 11 21
方法2:自动转义模式特殊字符
如果必须使用模式匹配(比如需要结合其他模式规则),可以写一个函数自动转义所有模式特殊字符:
-- 转义模式串中的特殊字符 local function escape_pattern(s) -- 匹配所有Lua模式特殊字符,替换为带%前缀的转义形式 return s:gsub("[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%1") end local str = "copper-ore-mining-drone-10" local sub = "mining-drone" local escaped_sub = escape_pattern(sub) print(str:find(escaped_sub)) -- 输出 11 21
另外,你之前转义出错是因为Lua里的转义符是%而非\,用\会触发无效转义错误,正确的单个连字符转义是%-,但显然用plain=true的方法更省心。
内容的提问来源于stack exchange,提问作者AivanF.
相关产品推荐
相关产品推荐

