首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Lua -如果在2个特殊字符之间,则使用string.find返回true

Lua -如果在2个特殊字符之间,则使用string.find返回true
EN

Stack Overflow用户
提问于 2019-02-08 14:00:37
回答 2查看 702关注 0票数 2

我需要一个模式,它将与string.find (或string.match,如果必要)将返回true,如果“表路径”字符串匹配。这是我的函数:

代码语言:javascript
运行
复制
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")); -- prints "blue";

上面的代码可以工作,但我现在想将模式更改为:

"module.<ANY>.color",其中<ANY>是“模块”的任何子表,也有一个称为"color“的子表,所以当向下遍历该表时,无论使用哪个表,都会返回一个值(不必是外观表):

代码语言:javascript
运行
复制
-- should also print "blue" ("setting." should not be required);
print(FindValueFromPattern(tbl, "module.<ANY>.color"));

我可能需要更改逻辑以在表中插入找到的值,然后在for循环之后返回表,而不是直接返回找到的值,但我很快就写了这段代码来说明这个问题。

所以问题是,这种模式是什么样子的?谢谢。

EN

Stack Overflow用户

发布于 2019-02-08 19:51:10

你在那里做的事情效率极低。一种更好的方法是在每个.处拆分字符串,并只对表进行索引。

一个不接受"any“的简单版本可能如下所示

代码语言:javascript
运行
复制
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

添加Any键的可能性(他...他...他...)会增加一些复杂性并需要一个循环,但这也是可行的

代码语言:javascript
运行
复制
    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

这应该可以做你想要的事情。只需将"*“更改为您想要的占位符。

票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54586772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档