Lua中的LPeg.re大小写不敏感匹配
2016-6-14 14:4:47
收藏:0
阅读:72
评论:2
我对Lua中的"LPeg"和"re"模块都很陌生,目前我想基于以下规则编写一个模式:
- 匹配以"gv_$/gv$/v$/v_$/x$/xv$/dba_/all_/cdb_"开头的字符串,并且前缀"SYS.%s*"或"PUBLIC.%s*"是可选的。
- 字符串不应跟随字母数字,即该模式不会匹配"XSYS.DBA_OBJECTS",因为它跟随"X"。
- 模式不区分大小写。
例如,下面的字符串应该匹配该模式:
,sys.dba_objects, --应该返回 "sys.dba_objects"
SyS.Dba_OBJECTS
cdb_objects
dba_hist_snapshot) --应该返回 "dba_hist_snapshot"
目前我的模式只能匹配大写非字母数字+字符串:
p=re.compile[[
pattern <- %W {owner* name}
owner <- 'SYS.'/ 'PUBLIC.'
name <- {prefix %a%a (%w/"_"/"$"/"#")+}
prefix <- "GV_$"/"GV$"/"V_$"/"V$"/"DBA_"/"ALL_"/"CDB_"
]]
print(p:match(",SYS.DBA_OBJECTS"))
我的问题是:
- 如何实现大小写不敏感匹配?有一些关于解决方案的主题,但是我太新手了,无法理解。
- 如何仅返回匹配的字符串,而不必额外添加%W?类似于Java中的"(?=...)"
如果您能提供模式或相关函数,将不胜感激。
点赞
用户3754826
最终我得到了一个解决方案,但不够优雅,即在re.compile、re.find、re.match和re.gsub函数中添加一个额外的参数case_insensitive。当参数值为true时,调用case_insensitive_pattern重写模式:
...
local fmt="[%s%s]"
local function case_insensitive_pattern(quote,pattern)
-- 查找可选的 '%' (group 1),后跟任何字符 (group 2)
local stack={}
local is_letter=nil
local p = pattern:gsub("(%%?)(.)",
function(percent, letter)
if percent ~= "" or not letter:match("%a") then
-- 如果 '%' 匹配,或者`letter`不是字母,则"原样返回"
if is_letter==false then
stack[#stack]=stack[#stack]..percent .. letter
else
stack[#stack+1]=percent .. letter
is_letter=false
end
else
if is_letter==false then
stack[#stack]=quote..stack[#stack]..quote
is_letter=true
end
-- 否则,返回大小写不敏感的字符类所匹配的字母
stack[#stack+1]=fmt:format(letter:lower(), letter:upper())
end
return ""
end)
if is_letter==false then
stack[#stack]=quote..stack[#stack]..quote
end
if #stack<2 then return stack[1] or (quote..pattern..quote) end
return '('..table.concat(stack,' ')..')'
end
local function compile (p, defs, case_insensitive)
if mm.type(p) == "pattern" then return p end -- 已编译
if case_insensitive==true then
p=p:gsub([[(['"'])([^\n]-)(%1)]],case_insensitive_pattern):gsub("%(%s*%((.-)%)%s*%)","(%1)")
end
local cp = pattern:match(p, 1, defs)
if not cp then error("incorrect pattern", 3) end
return cp
end
...
2016-07-01 17:40:31
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的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 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
你可以尝试调整此语法:
local re = require're' local p = re.compile[[ pattern <- ((s? { <name> }) / s / .)* !. name <- (<owner> s? '.' s?)? <prefix> <ident> owner <- (S Y S) / (P U B L I C) prefix <- (G V '_'? '$') / (V '_'? '$') / (D B A '_') / (C D B '_') ident <- [_$#%w]+ s <- (<comment> / %s)+ comment <- '--' (!%nl .)* A <- [aA] B <- [bB] C <- [cC] D <- [dD] G <- [gG] I <- [iI] L <- [lL] P <- [pP] S <- [sS] U <- [uU] V <- [vV] Y <- [yY] ]] local m = { p:match[[ ,sys.dba_objects, --should return "sys.dba_objects" SyS.Dba_OBJECTS cdb_objects dba_hist_snapshot) --should return "dba_hist_snapshot" ]] } print(unpack(m))上面的代码将打印匹配表
m:请注意,大小写不敏感很难通过词法分析器实现,因此每个字母都必须有一个单独的规则 - 最终需要更多这样的规则。
此语法处理示例中的注释并跳过它们以及空格符,因此“应返回”后的匹配不会出现在输出中。
您可以调整
prefix和ident规则以指定对象名称中的其他前缀和允许的字符。注意:
!.表示文件结束。!%nl表示“不是行尾”。!p和&p构建非消耗模式,即在匹配时不会增加当前输入指针(仅对输入进行测试)。注意2:使用
unpack进行print是一个不好的方法。注意3:这是一个LPEG可追踪的 re,可用于调试语法。在
re.compile的第三个参数中传递true以获取测试/匹配/跳过每个规则和位置访问时的执行跟踪。