This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
TheHappyBukkit's profile picture

split() function

Started by TheHappyBukkit, 11 November 2012 - 09:06 AM
TheHappyBukkit #1
Posted 11 November 2012 - 10:06 AM
Hey guys,

Is there a snippet of code that would let you split a string by a delimiter?

For example:


toSplit = This, is, a, test.
table = split(toSplit, ", ")

Thanks!
PixelToast #2
Posted 11 November 2012 - 10:08 AM

function split(T,func)
if func then
  T=func(T)
end
local Out={}
if type(T)=="table" then
  for k,v in pairs(T) do
   Out[split(k)]=split(v)
  end
else
  Out=T
end
return Out
end
func is optional
TheHappyBukkit #3
Posted 11 November 2012 - 10:14 AM
Thanks! I will try it out in a second.
TheHappyBukkit #4
Posted 11 November 2012 - 10:24 AM
This isn't exactly what I am looking for. This just returns a string as a table. I am looking to split up parts of the string by the second argument.

Here is an example (not lua): http://www.dotnetperls.com/split

I have seen lua split strings, but I am not sure if they would work with CC.
Kingdaro #5
Posted 11 November 2012 - 10:27 AM
There's a "string exploding" function on the love2d wiki that basically does the same thing.

function string.explode(str, div)
    assert(type(str) == "string" and type(div) == "string", "invalid arguments")
    local o = {}
    while true do
        local pos1,pos2 = str:find(div)
        if not pos1 then
            o[#o+1] = str
            break
        end
        o[#o+1],str = str:sub(1,pos1-1),str:sub(pos2+1)
    end
    return o
end
https://love2d.org/wiki/String_exploding

I used this in a recent project and renamed it to "split".
TheHappyBukkit #6
Posted 11 November 2012 - 11:24 AM
Thanks!
billysback #7
Posted 11 November 2012 - 12:15 PM
although this has been awnsered; the function I use (which I just looked up like a month ago) is:

local function split(str, pat)
    local t = {}  -- NOTE: use {n = 0} in Lua-5.0
    if str ~= nil then
       local fpat = "(.-)" .. pat
       local last_end = 1
       local s, e, cap = str:find(fpat, 1)
       while s do
          if s ~= 1 or cap ~= "" then
         table.insert(t,cap)
          end
          last_end = e+1
          s, e, cap = str:find(fpat, last_end)
       end
       if last_end <= #str then
          cap = str:sub(last_end)
          table.insert(t, cap)
       end
    else
        print("##ERROR failed to split ["..str.."] by:"..pat)
    end
    return t
end
Espen #8
Posted 11 November 2012 - 12:53 PM
Sharing is caring, so here's my version with regular expressions:
local function split( _sInput, _sDelimiter )
    local tReturn = {}
    local delimiter = string.gsub( _sDelimiter, "([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1" )
    local searchPattern = "([^"..delimiter.."]+)"..delimiter.."?"

    for match in string.gmatch( _sInput, searchPattern ) do
        table.insert( tReturn, match )
    end
    return tReturn
end

With comments:
Spoiler
--[[
    _sInput	= String to be split.
    _sDelimiter	= Character to split at.
	
    Returns: a table with delimited values.
]]
local function split( _sInput, _sDelimiter )
    local tReturn = {}
    -- Prepend % to magical characters.
    local delimiter = string.gsub( _sDelimiter, "([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1" )
    -- 1 or more characters that are NOT the delimiter, followed by 0 or 1 delimiters; capture the former
    local searchPattern = "([^"..delimiter.."]+)"..delimiter.."?"
    -- Go through all matches and fill the return-table with the captures.
    for match in string.gmatch( _sInput, searchPattern ) do
        table.insert( tReturn, match )
    end
    return tReturn
end

Edit: Removed comments as it looks less confusing. Added version with comments separately