不区分大小写的Lua模式匹配。
2012-7-9 19:35:56
收藏:0
阅读:236
评论:2
我正在为运行 Windows CE 6/7 的移动设备编写 Lua 中的 grep 实用程序,但是我在实现不区分大小写的匹配模式时遇到了一些问题。显然的解决方案是将所有内容转换为大写(或小写),但由于字符类,这并不那么简单。
我能想到的唯一解决方法是将模式中的文字本身转换为大写。
到目前为止,这是我所拥有的内容:
function toUpperPattern(instr)
-- 检查第一个字符
if string.find(instr, "^%l") then
instr = string.upper(string.sub(instr, 1, 1)) .. string.sub(instr, 2)
end
-- 检查模式的其余部分
while 1 do
local a, b, str = string.find(instr, "[^%%](%l+)")
if not a then break end
if str then
instr = string.sub(instr, 1, a) .. string.upper(string.sub(instr, a+1, b)) .. string.sub(instr, b + 1)
end
end
return instr
end
我不愿承认实现这一步骤所用的时间有多长,而且我仍然可以立即发现在处理转义百分号 '%%' 等问题时会出现问题。
我想这必须是一个相当常见的问题,但是我似乎找不到关于这个主题的太多内容。 有更简单(或至少完整)的方法吗? 我开始疯了...... 希望你们Lua大师能启发我!
点赞
用户6544989
do
local p = re.compile([[
pattern <- ( {b} / {escaped} / brackets / other)+
b <- "%b" . .
escaped <- "%" .
brackets <- { "[" ([^]%]+ / escaped)* "]" }
other <- [^[%]+ -> cases
]], {
cases = function(str) return (str:gsub('%a',function(a) return '['..a:lower()..a:upper()..']' end)) end
})
local pb = re.compile([[
pattern <- ( {b} / {escaped} / brackets / other)+
b <- "%b" . .
escaped <- "%" .
brackets <- {: {"["} ({escaped} / bcases)* {"]"} :}
bcases <- [^]%]+ -> bcases
other <- [^[%]+ -> cases
]], {
cases = function(str) return (str:gsub('%a',function(a) return '['..a:lower()..a:upper()..']' end)) end
, bcases = function(str) return (str:gsub('%a',function(a) return a:lower()..a:upper() end)) end
})
function iPattern(pattern,brackets)
('sanity check'):find(pattern)
return table.concat({re.match(pattern, brackets and pb or p)})
end
end
local test = '[ab%c%]d%%]+ o%%r %bnm'
print(iPattern(test)) -- [ab%c%]d%%]+ [oO]%%[rR] %bnm
print(iPattern(test,true)) -- [aAbB%c%]dD%%]+ [oO]%%[rR] %bnm
print(('qwe [%D]% O%r n---m asd'):match(iPattern(test, true))) -- %D]% O%r n---m
纯 Lua 版本:
由于 Lua 模式不像正则表达式(abc|something)那样具有选择,所以必须分析字符串中的所有字符以将其转换为正确的模式。
function iPattern(pattern, brackets)
('sanity check'):find(pattern)
local tmp = {}
local i=1
while i <= #pattern do -- 'for' don't let change counter
local char = pattern:sub(i,i) -- 当前字符
if char == '%' then
tmp[#tmp+1] = char -- 添加到 tmp 表中
i=i+1 -- 下一个字符位置
char = pattern:sub(i,i)
tmp[#tmp+1] = char
if char == 'b' then -- '%bxy' - 添加下两个字符
tmp[#tmp+1] = pattern:sub(i+1,i+2)
i=i+2
end
elseif char=='[' then -- 括号
tmp[#tmp+1] = char
i = i+1
while i <= #pattern do
char = pattern:sub(i,i)
if char == '%' then -- 没有 '%bxy' 在括号里
tmp[#tmp+1] = char
tmp[#tmp+1] = pattern:sub(i+1,i+1)
i = i+1
elseif char:match("%a") then -- 字母
tmp[#tmp+1] = not brackets and char or char:lower()..char:upper()
else -- 其他的
tmp[#tmp+1] = char
end
if char==']' then break end -- 关闭括号
i = i+1
end
elseif char:match("%a") then -- 字母
tmp[#tmp+1] = '['..char:lower()..char:upper()..']'
else
tmp[#tmp+1] = char -- 其他的
end
i=i+1
end
return table.concat(tmp)
end
local test = '[ab%c%]d%%]+ o%%r %bnm'
print(iPattern(test)) -- [ab%c%]d%%]+ [oO]%%[rR] %bnm
print(iPattern(test,true)) -- [aAbB%c%]dD%%]+ [oO]%%[rR] %bnm
print(('qwe [%D]% O%r n---m asd'):match(iPattern(test, true))) -- %D]% O%r n---m
2016-07-04 06:55:08
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的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中获取用户配置主目录的跨平台方法
function case_insensitive_pattern(pattern) -- 查找可选的 '%'(第一个组)后跟任何字符(第二个组) local p = pattern:gsub("(%%?)(.)", function(percent, letter) if percent ~= "" or not letter:match("%a") then -- 如果 '%' 匹配或 'letter' 不是字母,返回“原样” return percent .. letter else -- 否则,返回大小写不敏感的字符类 return string.format("[%s%s]", letter:lower(), letter:upper()) end end) return p end print(case_insensitive_pattern("xyz = %d+ or %% end"))输出结果为: