Lua - 使用 string.find 来判断是否在两个特定字符之间
2019-2-8 6:18:35
收藏:0
阅读:98
评论:2
我需要一个能够与 string.find(或如果必要的话是 string.match)一起工作且能够匹配“表路径”字符串的模式。这是我的函数:
local function FindValueFromPattern(myTable, pattern, previousPath)
for key, value in pairs(myTable) do
local path;
if (not previousPath) then
path = key;
else
path = string.format("%s.%s", previousPath, key);
end
if (path:find(pattern)) then
return value;
elseif (type(value) == "table") then
value = FindValueFromPattern(value, pattern, path);
if (value ~= nil) then
return value;
end
end
end
return nil;
end
local tbl = {}
tbl.settings = {};
tbl.settings.module = {};
tbl.settings.module.appearance = {};
tbl.settings.module.appearance.color = "blue";
print(FindValueFromPattern(tbl, "settings.module.appearance.color")); -- 输出 "blue";
上面的代码是有效的,但我现在想将模式更改为:
"module.<ANY>.color" 其中 <ANY> 是“module”下的任何子表,也有一个名为“color”的子表,因此在遍历表时,无论使用哪个表都会返回一个值(不必是 appearance 表):
-- 也应该输出 "blue"(不需要 "setting.");
print(FindValueFromPattern(tbl, "module.<ANY>.color"));
我可能不会立即返回找到的值,而是要更改逻辑以在 for 循环后将找到的值插入到表中,然后返回该表,但我很快写下了这个问题。
所以问题是,该模式会是什么样子呢?谢谢。
点赞
用户7396148
我使用 gmatch 和模式 %.*([^.]+) 对所提供的 keys 中的每个 key 进行迭代。
该函数可以更改为输出找到的所有 color 的表,但目前仅返回单个值。返回的值是找到的 color,如果没有找到匹配项,则返回 nil。
function FindValueFromPattern(tab, keys)
local t_ref = tab
for k in keys:gmatch("%.*([^.]+)") do
if k == "<ANY>" and type(t_ref) == "table" then
local temp1
local temp2
for any in pairs(t_ref) do
local new_keys = keys:gsub(k, any)
temp1 = FindValueFromPattern(tab, new_keys)
new_keys = keys:gsub(k, any .. ".<ANY>")
temp2 = FindValueFromPattern(tab, new_keys)
if temp1 or temp2 then
break
end
end
t_ref = temp1 or temp2
break
else
if t_ref == nil or type(t_ref) ~= "table" then
t_ref = nil
break
end
t_ref = t_ref[k]
end
end
return t_ref
end
使用示例:
sample = {
a = {
b = {
c = {
color = "blue",
},
roloc = 1,
color = "red",
},
d = {
e = {
color = "purple",
},
roloc = "wolley",
color = "yellow",
},
}
}
colorFound = FindValueFromPattern(sample, "a.<ANY>.color")
if colorFound then
print("Found: " .. colorFound )
else
print("No matches found")
end
>> Found: red
请记住,其行为是不确定的,输出可能是 yellow 而不是 red,直到代码被运行才能知道它将是哪个输出。
2019-02-11 19:38:17
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

你现在在做的非常低效。一个更好的方法是在每个
.上将字符串分割并索引表。一个简单版本,不接受 "any" 可以像这样:
function findintable(tab, path) local pos = path:find(".", 1, true) if pos then local tab = tab[path:sub(1, pos-1)] if not type(tab) then error("Expected value to be table, got "..type(tab), 1) end return findintable(tab, path:sub(pos+1, -1)) else return tab[path] end end如果要添加 任意键 (嘿嘿嘿...),它会增加一些复杂性并需要一个循环,但也是可行的。
function findintable(tab, path) local pos = path:find(".", 1, true) if not pos then return tab[path] end local key, rest = path:sub(1, pos-1), path:sub(pos+1, -1) if key == "*" then for k, v in pairs(tab) do if type(v)~="table" then return end local res = findintable(v, rest) if res then return res end end return else local tab = tab[path:sub(1, pos-1)] if not type(tab) then error("Expected value to be table, got "..type(tab), 1) end return findintable(tab, path:sub(pos+1, -1)) end end这样应该能够实现你想要的效果。只需将 "*" 更改为占位符即可。