#hmmm now if if the string has different
1 messages · Page 1 of 1 (latest)
I would instead use string .find and loop using character indices. You have control and it is probably more efficient.
yeah, i wrote a function like this months ago...
local startLoc = 1
local finalLoc = 0
while finalLoc < Database.baseList:len() do
_, startLoc = Database.baseList:find("\n\n\n[====]*\n*", startLoc)
startLoc = startLoc + 1
lastLoc, finalLoc = Database.baseList:find("\n\n\n[====]*\n*", startLoc)
lastLoc = lastLoc - 1
local expansionSet = Database.baseList:sub(startLoc, lastLoc)
local expansionName, factionData = expansionSet:match("^([^\n]+)\n(.*)")
startLoc = lastLoc
-- yadda yadda
but man... it seems much LESS efficient
It LOOKS less efficient, but I ask myself what is gmatch really doing?
yeah.. actually, i have no idea!
Besides, how many times are you going to do it?
just once right now, and then everytime a new expansion is released
In other words, maybe 10 or 20 times? You've already spent a lot more just thinking about it than the cost of running the "stupid" code!
lol! yeah, but i really love having great code that feels sleek to me, and is easy for me to read again in 8-12 months
quick question
with lua regex, [^\n]+ means everything that is not a new line. is there something similar for not just one character, but a string?
so like "everything that does not match '&$@'"
To my knowledge, nope. I haven't seen anything like that in any regex implementation.
regex processes characters, not words.
so when regexing for a [set], the set looks for all characters in the [set] individually, right? so [&$@] would look for a & OR $ OR @, correct?
yes
Note that $ would need to be escaped if you wanted a dollar sign as opposed to end of string
You can't use string.gmatch to identify a string of characters as a delimiter for your block (because the pattern description is at character level). Instead, you can write your own iterator utilising string.find and string.sub, more or less similar to the suggestion from @shell burrow and @fringe pulsar.
function getBlocks(s, delim, plain)
local findStart, blockStart = string.find(s, delim, 1, plain)
local length = #s
return function()
-- while still finding blocks
if findStart > 0 then
-- find the position of the delimiter of the next block
-- if not found, set it to end of string (-1)
local nextFindStart, nextBlockStart = string.find(s, delim, blockStart, plain)
nextFindStart = (nextFindStart or 0) - 1
-- retrieve block
local block = string.sub(s, blockStart + 1, nextFindStart)
-- update iterator variables
findStart, blockStart = nextFindStart, nextBlockStart
return block
end
end
end
For the block parser, you can use the standard line matching pattern with string.gmatch:
function parseBlock(block)
local out = {}
-- automatically ignore blank lines
for entry in string.gmatch(block, "([^\n]+)") do
table.insert(out, entry)
end
return out
end
Usage Example:
local s = [[
====
Faction 1
Card 1
Card 2
Card 3
====
Faction 2
Card 4
Card 5
Card 6
====
]]
local i = 1
for block in getBlocks(s, "====", true) do
print()
print(string.format("== %d ==", i))
local t = parseBlock(block)
if #t > 1 then
-- block processing here;
-- e.g. table.remove the first entry as faction name,
-- and then process the rest of the values via ipairs, etc.
print(logString(t))
else
print("EMPTY")
end
i = i + 1
end