I have string like this: something $asd:$test$,2$
I need to parse text in $
like a tree structure and start from children.
So, $test$
is parsed first and will be replaced by some function output. Let's assume this function output will be 1
. Now $asd:1,2$
(because $test$
got replaced with 1
) should be parsed next and also will be replaced by some function output. Let's say it will be string days: 1 nights: 2
.
The end result should be something days: 1 nights: 2
How it can be done? I tried to resolve it by gsub
function with regex, but seems it is not meant for this type of parsing.
CodePudding user response:
A little bit of recursion to save the day.
The *
and
are greedy operators so they try to capture as much as possible. This allows us to capture the entire string, remove the outside $ and repeat the check again. After all of that, we pass those captures through our function. Recursion keeps the code nice and clean without the use of a couple of loops tables.
local function someFunction(str)
if str == "test" then
return 1
elseif str == "asd:1,2" then
return "days: 1 nights: 2"
end
end
local function treeParser(str)
if str:find("%$(. )%$") then
local start, finish, capture = str:find("%$(. )%$")
return str:sub(1, start-1) .. someFunction(treeParser(capture)) .. str:sub(finish 1)
end
return str
end
print(treeParser("something $asd:$test$,2$"))
CodePudding user response:
Recursion with quadratic complexity is OK when the depth of tree is small enough.
local function someFunction(str)
if str == "test" then
return "1"
elseif str == "asd:1,2" then
return "days: 1 nights: 2"
end
end
local function calculate(str)
return someFunction(str:sub(2, -2):gsub("%b\1\2", calculate))
end
local function treeParser(str)
str = str:gsub("%$%f[%w]", "\1"):gsub("%$", "\2"):gsub("%b\1\2", calculate)
return str
end
print(treeParser("something $asd:$test$,2$"))