我正在制作一个JSON解析器,我正在寻找一种算法,可以找到所有匹配的括号([]
)和大括号({}
)并将它们放入带有位置的表中这对。
返回值的示例:
table[x][firstPos][secondPos] = type
table[x] = {firstPos, secondPos, bracketType}
编辑:让parse()
成为返回括号对的函数。设table
为parse()
函数返回的值。设codeString
为包含我想要检测的括号的字符串。设firstPos
为N
括号中第一个括号的位置。设secondPos
为N
括号中第二个括号的位置。设bracketType
为括号对的类型(“括号”或“括号”)。
示例:
如果您致电:
table = parse(codeString)
table[N][firstPos][secondPos]
等于type
。
答案 0 :(得分:1)
嗯,在简单的Lua中,你可以做这样的事情,同时考虑嵌套括号:
function bm(s)
local res ={}
if not s:match('%[') then
return s
end
for k in s:gmatch('%b[]') do
res[#res+1] = bm(k:sub(2,-2))
end
return res
end
当然,你可以很容易地将这一点概括为大括号,括号,等等(请记住模式中必要的[]转义,除了%b模式之外)。
如果您不限于普通Lua,可以使用LPeg获得更大的灵活性
如果您没有查找括号的内容,而是查找位置,则递归方法难以实现,因为您应该跟踪自己的位置。更容易就是走过字符串并在去的时候匹配它们:
function bm(s,i)
local res={}
res.par=res -- Root
local lev = 0
for loc=1,#s do
if s:sub(loc,loc) == '[' then
lev = lev+1
local t={par=res,start=loc,lev=lev} -- keep track of the parent
res[#res+1] = t -- Add to the parent
res = t -- make this the current working table
print('[',lev,loc)
elseif s:sub(loc,loc) == ']' then
lev = lev-1
if lev<0 then error('too many ]') end -- more closing than opening.
print(']',lev,loc)
res.stop=loc -- save bracket closing position
res = res.par -- revert to the parent.
end
end
return res
end
现在你已经拥有了所有匹配的括号,你可以遍历表格,提取所有位置。
答案 1 :(得分:0)
我想出了自己的算法。
function string:findAll(query)
local firstSub = 1
local lastSub = #query
local result = {}
while lastSub <= #self do
if self:sub(firstSub, lastSub) == query then
result[#result + 1] = firstSub
end
firstSub = firstSub + 1
lastSub = lastSub + 1
end
return result
end
function string:findPair(openPos, openChar, closeChar)
local counter = 1
local closePos = openPos
while closePos <= #self do
closePos = closePos + 1
if self:sub(closePos, closePos) == openChar then
counter = counter + 1
elseif self:sub(closePos, closePos) == closeChar then
counter = counter - 1
end
if counter == 0 then
return closePos
end
end
return -1
end
function string:findBrackets(bracketType)
local openBracket = ""
local closeBracket = ""
local openBrackets = {}
local result = {}
if bracketType == "[]" then
openBracket = "["
closeBracket = "]"
elseif bracketType == "{}" then
openBracket = "{"
closeBracket = "}"
elseif bracketType == "()" then
openBracket = "("
closeBracket = ")"
elseif bracketType == "<>" then
openBracket = "<"
closeBracket = ">"
else
error("IllegalArgumentException: Invalid or unrecognized bracket type "..bracketType.."\nFunction: findBrackets()")
end
local openBrackets = self:findAll(openBracket)
if not openBrackets[1] then
return {}
end
for i, j in pairs(openBrackets) do
result[#result + 1] = {j, self:findPair(j, openBracket, closeBracket)}
end
return result
end
将输出:
5 14
6 13
7 12
8 11
9 10