95 lines
2.0 KiB
Lua
95 lines
2.0 KiB
Lua
local function wrapEachItem(items, prefix, suffix)
|
|
local itemsWrapped = {}
|
|
|
|
for i, item in ipairs(items) do
|
|
itemsWrapped[i] = prefix .. item .. suffix
|
|
end
|
|
|
|
return itemsWrapped
|
|
end
|
|
|
|
local function getAllItemCombinationsConcatenated(aItems, bItems)
|
|
local combinations = {}
|
|
|
|
for _, a in ipairs(aItems) do
|
|
for _, b in ipairs(bItems) do
|
|
table.insert(combinations, a..b)
|
|
end
|
|
end
|
|
|
|
return combinations
|
|
end
|
|
|
|
local getItems -- Forward declaration.
|
|
|
|
local function getGroup(s, pos, depth)
|
|
local groupItems = {}
|
|
local foundComma = false
|
|
|
|
while pos <= #s do
|
|
local items
|
|
items, pos = getItems(s, pos, depth)
|
|
if pos > #s then break end
|
|
|
|
for _, item in ipairs(items) do
|
|
table.insert(groupItems, item)
|
|
end
|
|
|
|
local c = s:sub(pos, pos)
|
|
|
|
if c == "}" then -- Possibly end of group.
|
|
if foundComma then return groupItems, pos+1 end
|
|
return wrapEachItem(groupItems, "{", "}"), pos+1 -- No group.
|
|
|
|
elseif c == "," then
|
|
foundComma, pos = true, pos+1
|
|
end
|
|
end
|
|
|
|
return nil -- No group.
|
|
end
|
|
|
|
function getItems(s, pos, depth)
|
|
local items = {""}
|
|
|
|
while pos <= #s do
|
|
local c = s:sub(pos, pos)
|
|
|
|
if depth > 0 and (c == "," or c == "}") then -- End of item in surrounding group.
|
|
return items, pos
|
|
end
|
|
|
|
local groupItems, nextPos = nil
|
|
if c == "{" then -- Possibly start of a group.
|
|
groupItems, nextPos = getGroup(s, pos+1, depth+1)
|
|
end
|
|
|
|
if groupItems then
|
|
items, pos = getAllItemCombinationsConcatenated(items, groupItems), nextPos
|
|
else
|
|
if c == "\\" and pos < #s then -- Escaped character.
|
|
pos = pos + 1
|
|
c = c .. s:sub(pos, pos)
|
|
end
|
|
items, pos = wrapEachItem(items, "", c), pos+1
|
|
end
|
|
end
|
|
|
|
return items, pos
|
|
end
|
|
|
|
local tests = [[
|
|
~/{Downloads,Pictures}/*.{jpg,gif,png}
|
|
It{{em,alic}iz,erat}e{d,}, please.
|
|
{,{,gotta have{ ,\, again\, }}more }cowbell!
|
|
{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}
|
|
]]
|
|
|
|
for test in tests:gmatch"[^\n]+" do
|
|
print(test)
|
|
for _, item in ipairs(getItems(test, 1, 0)) do
|
|
print("\t"..item)
|
|
end
|
|
print()
|
|
end
|