设置动态模式匹配器的方法
way to set dynamic pattern matcher
请查看这个问题 ,它具有我需要的预期行为。
更改
在模式 ^u.meta(\.|$)
或 lua '^u%.meta%f[[=14=].]'
或 '^u%.meta%f[%z.]'
中,我需要的更改是 u.meta
可以是用户从变量定义的任何内容。模式应为 generic/dynamic 以匹配变量中设置的内容。
例如:
-- should return 'u.meta', and pattern should match
local pattern = 'u.meta'
print(string.match("u.meta.admin", '^u%.meta%f[[=10=].]')) -- u.meta
-- should return 'nil', and pattern should fail
local pattern = 'u.meta'
print(string.match("u.domain.admin", '^u%.meta%f[[=10=].]')) -- nil
-- should return 'anything.anything', and pattern should match
local pattern = 'anything.anything'
print(string.match("anything.anything.something", '^anything%.anything%f[[=10=].]') -- anything.anything
-- should return nil, and pattern should fail
local pattern = 'anything.anything'
print(string.match("fake.fake.something", '^anything%.anything%f[[=10=].]') -- nil
解决方案 1
所以,如果可能的话,我的想法是 lua 模式中的 interpolation
。
"^#{pattern}%f[[=11=].]"
工作解决方案 2
我已经在方法的帮助下让它工作了。但我仍然必须手动调用这些模式。如果我们能从模式本身解决这个问题,那就太好了
示例:
function pattern_matcher(v, pattern) return string.match(v, pattern) end
print(pattern_matcher("fake.fake.something", '^u%.meta%f[%z.]')) -- nil
print(pattern_matcher("u.meta.something", '^u%.meta%f[%z.]')) -- u.meta
print(pattern_matcher("u.meta_something", '^u%.meta%f[%z.]')) -- nil
print(pattern_matcher("u.meta-something", '^u%.meta%f[%z.]')) -- nil
如果您需要支持用户输入作为正则表达式模式的文字部分,您需要引入一个转义函数,以便使用 %
转义所有魔术字符。然后,只需连接自定义边界(^
字符串开头,以及
%f[%z.]
表示字符串或点的结尾)。
function escape (s)
return string.gsub(s, '[.*+?^$()[%%-]', "%%%0")
end
function pattern_matcher(v, pattern) return string.match(v, pattern) end
word = "u.meta"
print(pattern_matcher("u.meta.something", '^' .. escape(word) .. '%f[%z.]')) -- u.meta
在 escape
函数中,替换模式中的前两个 %%
表示一个 %
,而 %0
反向引用整个匹配(其中一个 magic characters)
这是我的最终解决方案:
-- USAGE:
--
-- local t = {}
-- t['roles'] = 'u.meta.admin'
-- match_roles(t, 'u.meta') -- u.meta
-- match_roles(t, 'u.fake') -- nil
--
-- SOLUTION 1
--------------
--
-- function u_meta(v) return string.match(v, '^u%.meta%f[%z.]') end
-- function u_domain(v) return string.match(v, '^u%.domain%f[%z.]') end
--
-- function match_roles(table, pattern)
-- for _, value in pairs(table) do
-- if pattern == "u.meta" then
-- if pattern == u_meta(value) then return true end
-- elseif pattern == "u.domain" then
-- if pattern == u_domain(value) then return true end
-- end
-- return false
-- end
-- end
-- SOLUTION 2
---------------
--
-- function pattern_matcher(v, p) return string.match(v, p) end
-- function match_roles(table, role, pattern)
-- for _, value in pairs(table) do
-- if role == pattern_matcher(value, pattern) then return true end
-- return false
-- end
-- end
-- SOLUTIN - 3 (GENERIC SOLUTION) - Thanks Wiktor for pattern
---------------------------------
function escape (s) return string.gsub(s, '[.*+?^$()[%%-]', "%%%0") end
function pattern_matcher(v, pattern) return string.match(v, pattern) end
function match_roles(table, pattern)
for _, value in pairs(table) do
if pattern == pattern_matcher(value, '^' .. escape(pattern) .. '%f[%z.]') then return true end
return false
end
end
-- UNIT TEST
-- ---------
--
-- Below section covers unit test in lua.
-- we are using `luaunit` unit-testing framework that works for lua.
-- NOTE: LuaUnit works with Lua 5.1, 5.2, 5.3 and luajit (v1 and v2.1),
-- http://luaunit.readthedocs.org/en/latest/
--
package.path = './lib/?.lua;' .. package.path
luaunit = require('luaunit')
local t = {}
function test_meta_user_should_be_true()
t["roles"] = 'u.meta.admin.system'
luaunit.assertEquals( match_roles(t, 'u.meta'), true )
end
function test_meta_admin_should_be_true()
t["roles"] = 'u.meta.admin'
luaunit.assertEquals( match_roles(t, 'u.meta'), true )
end
function test_system_admin_should_be_true()
t["roles"] = 'u.meta.admin.system'
luaunit.assertEquals( match_roles(t, 'u.meta'), true )
end
function test_invalid_meta_admin_should_be_false()
t["roles"] = 'u.meta_admin'
luaunit.assertEquals( match_roles(t, 'u.meta'), false )
end
function test_invalid_meta_admin_system_should_be_false()
t["roles"] = 'u.meta_admin_system'
luaunit.assertEquals( match_roles(t, 'u.meta'), false )
end
function test_invalid_role_should_be_false()
t["roles"] = 'u.meta-admin'
luaunit.assertEquals( match_roles(t, 'u.meta'), false )
end
function test_domain_should_not_allow_in_meta()
t['roles'] = 'u.domain'
luaunit.assertEquals( match_roles(t, 'u.meta'), false )
end
function test_domain_user_should_be_true()
t["roles"] = 'u.domain'
luaunit.assertEquals( match_roles(t, 'u.domain'), true )
end
function test_domain_admin_should_be_true()
t["roles"] = 'u.domain.admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), true )
end
function test_fake_domain_admin_should_be_falsy()
t["roles"] = 'u.domain_admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_fake_role_should_be_falsy()
t["roles"] = 'u.domain-admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_user_should_either_domain_or_meta ()
t["roles"] = 'u'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_meta_user_in_domain_should_be_false ()
t["roles"] = 'u.meta'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_meta_admin_in_domain_should_be_false ()
t["roles"] = 'u.meta.admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_system_admin_in_domain_should_be_false ()
t["roles"] = 'u.meta.admin.system'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_fake_meta_admin_in_domain_should_be_true ()
t["roles"] = 'u.meta_admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_fake_system_admin_in_domain_should_be_true ()
t["roles"] = 'u.meta_admin_system'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_fake_meta_role_in_domain_should_be_true ()
t["roles"] = 'u.meta-admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_anything_should_match_correct_pattern()
t['roles'] = 'a.b.c.z'
luaunit.assertEquals( match_roles(t, 'a.b'), true )
end
function test_anything_should_fail_incorrect_pattern()
t['roles'] = 'a.b_c'
luaunit.assertEquals( match_roles(t, 'a.b'), false )
end
-- Exit after testcases finished
os.exit( luaunit.LuaUnit.run() )
请查看这个问题
更改
在模式 ^u.meta(\.|$)
或 lua '^u%.meta%f[[=14=].]'
或 '^u%.meta%f[%z.]'
中,我需要的更改是 u.meta
可以是用户从变量定义的任何内容。模式应为 generic/dynamic 以匹配变量中设置的内容。
例如:
-- should return 'u.meta', and pattern should match
local pattern = 'u.meta'
print(string.match("u.meta.admin", '^u%.meta%f[[=10=].]')) -- u.meta
-- should return 'nil', and pattern should fail
local pattern = 'u.meta'
print(string.match("u.domain.admin", '^u%.meta%f[[=10=].]')) -- nil
-- should return 'anything.anything', and pattern should match
local pattern = 'anything.anything'
print(string.match("anything.anything.something", '^anything%.anything%f[[=10=].]') -- anything.anything
-- should return nil, and pattern should fail
local pattern = 'anything.anything'
print(string.match("fake.fake.something", '^anything%.anything%f[[=10=].]') -- nil
解决方案 1
所以,如果可能的话,我的想法是 lua 模式中的 interpolation
。
"^#{pattern}%f[[=11=].]"
工作解决方案 2
我已经在方法的帮助下让它工作了。但我仍然必须手动调用这些模式。如果我们能从模式本身解决这个问题,那就太好了
示例:
function pattern_matcher(v, pattern) return string.match(v, pattern) end
print(pattern_matcher("fake.fake.something", '^u%.meta%f[%z.]')) -- nil
print(pattern_matcher("u.meta.something", '^u%.meta%f[%z.]')) -- u.meta
print(pattern_matcher("u.meta_something", '^u%.meta%f[%z.]')) -- nil
print(pattern_matcher("u.meta-something", '^u%.meta%f[%z.]')) -- nil
如果您需要支持用户输入作为正则表达式模式的文字部分,您需要引入一个转义函数,以便使用 %
转义所有魔术字符。然后,只需连接自定义边界(^
字符串开头,以及
%f[%z.]
表示字符串或点的结尾)。
function escape (s)
return string.gsub(s, '[.*+?^$()[%%-]', "%%%0")
end
function pattern_matcher(v, pattern) return string.match(v, pattern) end
word = "u.meta"
print(pattern_matcher("u.meta.something", '^' .. escape(word) .. '%f[%z.]')) -- u.meta
在 escape
函数中,替换模式中的前两个 %%
表示一个 %
,而 %0
反向引用整个匹配(其中一个 magic characters)
这是我的最终解决方案:
-- USAGE:
--
-- local t = {}
-- t['roles'] = 'u.meta.admin'
-- match_roles(t, 'u.meta') -- u.meta
-- match_roles(t, 'u.fake') -- nil
--
-- SOLUTION 1
--------------
--
-- function u_meta(v) return string.match(v, '^u%.meta%f[%z.]') end
-- function u_domain(v) return string.match(v, '^u%.domain%f[%z.]') end
--
-- function match_roles(table, pattern)
-- for _, value in pairs(table) do
-- if pattern == "u.meta" then
-- if pattern == u_meta(value) then return true end
-- elseif pattern == "u.domain" then
-- if pattern == u_domain(value) then return true end
-- end
-- return false
-- end
-- end
-- SOLUTION 2
---------------
--
-- function pattern_matcher(v, p) return string.match(v, p) end
-- function match_roles(table, role, pattern)
-- for _, value in pairs(table) do
-- if role == pattern_matcher(value, pattern) then return true end
-- return false
-- end
-- end
-- SOLUTIN - 3 (GENERIC SOLUTION) - Thanks Wiktor for pattern
---------------------------------
function escape (s) return string.gsub(s, '[.*+?^$()[%%-]', "%%%0") end
function pattern_matcher(v, pattern) return string.match(v, pattern) end
function match_roles(table, pattern)
for _, value in pairs(table) do
if pattern == pattern_matcher(value, '^' .. escape(pattern) .. '%f[%z.]') then return true end
return false
end
end
-- UNIT TEST
-- ---------
--
-- Below section covers unit test in lua.
-- we are using `luaunit` unit-testing framework that works for lua.
-- NOTE: LuaUnit works with Lua 5.1, 5.2, 5.3 and luajit (v1 and v2.1),
-- http://luaunit.readthedocs.org/en/latest/
--
package.path = './lib/?.lua;' .. package.path
luaunit = require('luaunit')
local t = {}
function test_meta_user_should_be_true()
t["roles"] = 'u.meta.admin.system'
luaunit.assertEquals( match_roles(t, 'u.meta'), true )
end
function test_meta_admin_should_be_true()
t["roles"] = 'u.meta.admin'
luaunit.assertEquals( match_roles(t, 'u.meta'), true )
end
function test_system_admin_should_be_true()
t["roles"] = 'u.meta.admin.system'
luaunit.assertEquals( match_roles(t, 'u.meta'), true )
end
function test_invalid_meta_admin_should_be_false()
t["roles"] = 'u.meta_admin'
luaunit.assertEquals( match_roles(t, 'u.meta'), false )
end
function test_invalid_meta_admin_system_should_be_false()
t["roles"] = 'u.meta_admin_system'
luaunit.assertEquals( match_roles(t, 'u.meta'), false )
end
function test_invalid_role_should_be_false()
t["roles"] = 'u.meta-admin'
luaunit.assertEquals( match_roles(t, 'u.meta'), false )
end
function test_domain_should_not_allow_in_meta()
t['roles'] = 'u.domain'
luaunit.assertEquals( match_roles(t, 'u.meta'), false )
end
function test_domain_user_should_be_true()
t["roles"] = 'u.domain'
luaunit.assertEquals( match_roles(t, 'u.domain'), true )
end
function test_domain_admin_should_be_true()
t["roles"] = 'u.domain.admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), true )
end
function test_fake_domain_admin_should_be_falsy()
t["roles"] = 'u.domain_admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_fake_role_should_be_falsy()
t["roles"] = 'u.domain-admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_user_should_either_domain_or_meta ()
t["roles"] = 'u'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_meta_user_in_domain_should_be_false ()
t["roles"] = 'u.meta'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_meta_admin_in_domain_should_be_false ()
t["roles"] = 'u.meta.admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_system_admin_in_domain_should_be_false ()
t["roles"] = 'u.meta.admin.system'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_fake_meta_admin_in_domain_should_be_true ()
t["roles"] = 'u.meta_admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_fake_system_admin_in_domain_should_be_true ()
t["roles"] = 'u.meta_admin_system'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_fake_meta_role_in_domain_should_be_true ()
t["roles"] = 'u.meta-admin'
luaunit.assertEquals( match_roles(t, 'u.domain'), false )
end
function test_anything_should_match_correct_pattern()
t['roles'] = 'a.b.c.z'
luaunit.assertEquals( match_roles(t, 'a.b'), true )
end
function test_anything_should_fail_incorrect_pattern()
t['roles'] = 'a.b_c'
luaunit.assertEquals( match_roles(t, 'a.b'), false )
end
-- Exit after testcases finished
os.exit( luaunit.LuaUnit.run() )