String API

I kept on finding myself in a place where I needed to use one of the string functions from Java, most of which aren’t in Lua. Things like string.split, string.replace, string.startsWith, or string.endsWith. So somehow I managed to create them using only string.find and string.sub. Then I made an API out of it. It’s very small, less than a hundred lines, but very useful. The setup function shows you how to use it, and when you run it what the results are. I’ll hopefully add much more to this in the future, but for now I think it’s good enough. Installer: https://gist.github.com/SkyTheCoder/5959465

Cool I’m going to play around with it. I usually end up rewritting code every time I need to split a string. I usually use string.gsub() for replace and remove.

I wanted to pass on a little trick. when you print a lot it’s a lot easier to use:

print([[One line of text
two lines of text
three lines of text
      --Keeps the formatting
]])

print([[
          *
         * *
        *   *
         * *
          *
]])

I was actually just wondering if you could use [[ ]] for strings about five minutes ago… But, as I use a lot of separate functions to print the usage out, I’m not sure that would work.

@SkyTheCoder, I have been recently using the lua string library for a project, and I was amazed at how powerful it was! Here is an example. I have rewritten your code to use the lua libraries (I left your code in for comparison) and you can decide which you prefer…

function string.replace(s, pattern, replacement)
    --[[local str = s
    while string.find(str, pattern) ~= nil do
        local pstart, pend = string.find(str, pattern)
        str = string.sub(str, 1, pstart - 1) .. replacement .. string.sub(str, pend + 1, string.len(str))
    end
    return str]]
    return (s:gsub(pattern, replacement))
end

function string.remove(s, pattern)
    return string.replace(s, pattern, "")
end

function string.startsWith(s, pattern)
    --[[local pstart, pend = string.find(s, pattern)
    return pstart == 1]]
    return not (not s:find("^"..pattern))
end

function string.endsWith(s, pattern)
    --[[local str = s
    local lastEnd = 0
    while string.find(str, pattern) ~= nil do
        local pstart, pend = string.find(str, pattern)
        str = string.sub(str, 1, pstart - 1) .. string.sub(str, pend + 1, string.len(str))
        lastEnd = pend
    end
    return lastEnd == string.len(s)]]
    return not (not s:find(pattern .. "$"))
end

function string.split(s, pattern)
    --[[local str = s
    str = str .. pattern
    local strTable = {}
    while string.find(str, pattern) ~= nil do
        local pstart, pend = string.find(str, pattern)
        table.insert(strTable, string.sub(str, 1, pstart - 1))
        local len = string.len(str)
        str = string.sub(str, pend + 1, len)
    end
    return strTable]]
    local t = {}
    for w in s:gmatch("[^"..pattern.."]+") do
        table.insert(t, w)
    end
    return t
end

function string.allChars(s)
    --[[local allChars = {}
    for i=1,string.len(s) do
        table.insert(allChars, string.sub(s, i, i))
    end
    return allChars]]
    local t = {}
    for c in s:gmatch(".") do
        table.insert(t, c)
    end
    return t
end

function string.slice(s, interval)
    --[[local allChars = string.allChars(s)
    for i=1,interval do
        table.insert(allChars, "")
    end
    local chars = {}
    for i=1,string.len(s),interval do
        local str = ""
        for j=0,interval-1 do
            str = str .. allChars[math.min(#allChars, i+j)]
        end
        table.insert(chars, str)
    end
    return chars]]
    t = {}
    for sl in s:gmatch(string.rep(".", interval)) do
        table.insert(t, sl)
    end
    return t
end

Just replace the String API tab with that :).
Oh, and @BriarFox… I see your nifty lua trick and raise you one.

print'look ma! No parenthesis!'
print[[I can write my lua with
no
bracket bars
No bracket bars
]]

@Jordan I’ve seen that one but it makes my head hurt :slight_smile: I love my parentheses . :stuck_out_tongue:

However I never thought about it with [[ ]]. I didn’t know that.

Heck for awhile I ended everything with ; but I got over it.

@Briarfox - Haha, same here.

@Briarfox @Jordan Where are you seeing all this g stuff? I haven’t seen any Lua string library, and it’s not documented.

http://lua-users.org/wiki/StringLibraryTutorial

I also use this Lua summary which includes string functions
http://lua-users.org/files/wiki_insecure/users/thomasl/luarefv51.pdf

Nice job @Jordan & @SkyTheCoder.
I just tested your function, and i thought my test code might be usefull for others, specially newbes, because the loadstring function is so tricky to use. So the only addition from me in this code below is the function showAndRun(s). Hope that helps sby.


-- forum strings

-- Use this function to perform your initial setup
function setup()
    showAndRun( [[ string.replace("Hello World!","World","baby") ]] )
    showAndRun( [[ string.remove("Hello World!","World") ]] )
    showAndRun( [[ string.startsWith("Hello World!","World!") ]] )
    showAndRun( [[ string.endsWith("Hello World!","World!") ]] )
    showAndRun( [[ string.split("Hello World!"," ") ]] )
    showAndRun( [[ string.allChars("Hello World!") ]] )
    showAndRun( [[ string.slice("Hello World!",3) ]] )
end
function showAndRun(s)
    print(s)
    local result = loadstring("return "..s) ()
    if type(result) == "table" then 
        result = "[ '"..table.concat(result,"' , '") .."' ]"
    end
    print(tostring(result))
    print("-------------------")
end

function string.replace(s, pattern, replacement)
    return (s:gsub(pattern, replacement))
end

function string.remove(s, pattern)
    return string.replace(s, pattern, "")
end

function string.startsWith(s, pattern)
    return not (not s:find("^"..pattern))
end

function string.endsWith(s, pattern)
    return not (not s:find(pattern .. "$"))
end

function string.split(s, pattern)
    local t = {}
    for w in s:gmatch("[^"..pattern.."]+") do
        table.insert(t, w)
    end
    return t
end

function string.allChars(s)
    local t = {}
    for c in s:gmatch(".") do
        table.insert(t, c)
    end
    return t
end

function string.slice(s, interval)
    t = {}
    for sl in s:gmatch(string.rep(".", interval)) do
        table.insert(t, sl)
    end
    return t
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)

    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    
end

@Jmv38 Nice job!

@Everyody Even if you use @Jordan’s version, I’m still proud of mine because it only uses string.find and string.sub, no string.gsub or string.gmatch.

@SkyTheCoder, I admit, your code was neat and very impressive. I just recommend you use the lua libraries as they are faster and more powerful :slight_smile: Very nice job though!