#hmmm now if if the string has different

1 messages · Page 1 of 1 (latest)

fringe pulsar
#

I would instead use string .find and loop using character indices. You have control and it is probably more efficient.

simple ore
#

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

fringe pulsar
#

It LOOKS less efficient, but I ask myself what is gmatch really doing?

simple ore
#

yeah.. actually, i have no idea!

fringe pulsar
#

Besides, how many times are you going to do it?

simple ore
#

just once right now, and then everytime a new expansion is released

fringe pulsar
#

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!

simple ore
#

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 '&$@'"

fringe pulsar
#

To my knowledge, nope. I haven't seen anything like that in any regex implementation.

#

regex processes characters, not words.

simple ore
#

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?

fringe pulsar
#

yes

#

Note that $ would need to be escaped if you wanted a dollar sign as opposed to end of string

vagrant patio
#

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