如何在lua中通过regexp重复匹配多个表达式
我正在学习lua。regexp中有一些问题。 我有一些字符串:如何在lua中通过regexp重复匹配多个表达式,regex,lua,Regex,Lua,我正在学习lua。regexp中有一些问题。 我有一些字符串: text = "aaab1aaac-aac1d2b5hhpt456d5h9h8" 我希望得到如下结果: "b1", "c1b2b5", "t4", "d5h9h8" 我编写代码如下 local st,ed while true do st,ed = string.find(text,"([a-z][1-9])+",ed) --the regexp if st==nil then break
text = "aaab1aaac-aac1d2b5hhpt456d5h9h8"
我希望得到如下结果:
"b1", "c1b2b5", "t4", "d5h9h8"
我编写代码如下
local st,ed
while true do
st,ed = string.find(text,"([a-z][1-9])+",ed) --the regexp
if st==nil then
break
else
print(string.sub(text,st,ed))
end
ed=ed+1
end
但是它没有打印正确的结果我不知道lua,但是这个正则表达式怎么样:
"((?:[a-z][1-9])+)"
正如@Yu Hao在一篇文章中已经提到的 , Lua模式与 “regex”我们大多数人都习惯了。 但这其实不是问题,因为Lua提供了优秀的 ,这是 由该语言的主要开发人员之一编写 您要求的模式可以用LPEG编写,如下所示:
local lpeg = require "lpeg"
local lpegmatch = lpeg.match
local R, C = lpeg.R, lpeg.C
local match_alpha_n_digit
do
local alpha = R "az" -- + R "AZ" -- for uppercase
local digit = R "09"
local sequence = C ((alpha * digit)^1) -- capture longest sequence of (alpha, digit) pairs
local pattern = (sequence + 1)^1
match_alpha_n_digit = function (str)
if not str or type (str) ~= "string" then return end
return lpegmatch (pattern, str)
end
end
text = "aaab1aaac-aac1d2b5hhpt456d5h9h8"
print (match_alpha_n_digit (text))
--- or capture the result in a table:
some_table = { match_alpha_n_digit (text) }
这样,它被包装在一个函数中match\u alpha\u n\u digit()
可以在表构造函数中调用的
也可以编写接收任意额外数据的模式
然后我们可以在匹配时使用参数检索的参数
捕获
().
例如,此方法允许使用函数迭代所有匹配项:
local lpeg = require "lpeg"
local lpegmatch = lpeg.match
local R, C = lpeg.R, lpeg.C
local Cmt, Carg = lpeg.Cmt, lpeg.Carg
local iter_alpha_n_digit
do
local alpha = R "az"
local digit = R "09"
local sequence = Cmt (C((alpha * digit)^1) * Carg (1),
function (_, _, match, fun)
fun (match)
return true
end)
local pattern = (sequence + 1)^1
iter_alpha_n_digit = function (str, fun)
if not str or type (str) ~= "string" then return end
if not fun or type (fun) ~= "function" then return end
return lpegmatch (pattern, str, nil, fun)
end
end
text = "aaab1aaac-aac1d2b5hhpt456d5h9h8"
iter_alpha_n_digit (text, print) -- iterate matches with the print() function
这里我们将内置的print()
函数应用于匹配项,但是
它可以是任何其他函数。尝试以下操作:
这里是使用LPEG的替代方案,在这种情况下,使用简单的循环是有效的:
function findzigs(text)
local items = {}
local zigzag = nil
local prevI1=-2
local i1,i2 = text:find("%a%d")
while i1~=nil do
local pair = text:sub(i1,i2)
if i1-2 == prevI1 then
zigzag = zigzag .. pair
else
if zigzag then table.insert(items, zigzag) end
zigzag = pair
end
prevI1 = i1
i1,i2 = text:find("%a%d", i2+1)
end
if zigzag then table.insert(items, zigzag) end
return items
end
可能会被清理以删除重复的“if-zigzag”和“text:find”,但你明白了。它会给出你所需要的结果 OP代码的真正问题在于Lua模式匹配与regex不同。这在正则表达式中有效,但在Lua模式中无效(除非有正则表达式库的支持)。不要这样做。我发现Lua不支持在“()”之后插入“+”。“([a-z][1-9])+”的表达式不能处理任何内容。另一种方式:
对于文本中的s:gsub(“%l%d”,“\0%0\0”):gsub(“%z%z”,”):gmatch“%z(.-)%z”不打印结束
回答得好。看起来是个更好的方法。谢谢。这很聪明,但需要太多的技巧来满足我的口味。我添加了一个基于简单循环的解决方案,其中包含文本:find(),更多行,但逻辑更清晰(IMO)。
function findzigs(text)
local items = {}
local zigzag = nil
local prevI1=-2
local i1,i2 = text:find("%a%d")
while i1~=nil do
local pair = text:sub(i1,i2)
if i1-2 == prevI1 then
zigzag = zigzag .. pair
else
if zigzag then table.insert(items, zigzag) end
zigzag = pair
end
prevI1 = i1
i1,i2 = text:find("%a%d", i2+1)
end
if zigzag then table.insert(items, zigzag) end
return items
end