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

Split works not properly after ran the first time ?!?

Started by mark332, 15 July 2013 - 02:30 PM
mark332 #1
Posted 15 July 2013 - 04:30 PM
Hello Guys, I'm working on a program, which has to split one string, two times to get all transmitted arguments, my problem is, that my split-function only splits once, and when I run it the second time, it returns just the input .. . ?!?

My Split function (placed in api "strings"):


function split(splitString, delimiter)
  local result = { }
  local from  = 1
  local delim_from, delim_to = string.find( splitString, delimiter, from  )
  while delim_from do
	table.insert( result, string.sub( splitString, from , delim_from-1 ) )
	from  = delim_to + 1
	delim_from, delim_to = string.find( splitString, delimiter, from  )
  end
  table.insert( result, string.sub( splitString, from  ) )
  return result
end

How I call it:

id, message = rednet.receive(6)					-- message == "bla=tree!SP!leave"
TableMessage = strings.split(message,"=")			   -- returns { "bla" , "tree!SP!leave" }
TableM = strings.split(TableMessage[2], "!SP!")		   -- returns { "tree!SP!leave" , nil}

Anyone know, how I can fix this ?

mark332


PS: If my english has mistakes, leave it be, I'm german ;)/>
LBPHacker #2
Posted 15 July 2013 - 05:03 PM
You had better use this for splitting strings:
strings.split = function(self, delimiter)
	local result = {}
	for word in string.gmatch(self, delimiter) do table.insert(result, word) end
	return result
end
Be aware that the delimiter has to be escaped properly. Eg. if the delimiter was a "[", you'd have to escape it like "%[".
EDIT: Read more about patterns here
EDIT #2: Characters in the delimiter which must be escaped by a "%": ^ [ ] ( ) - + . * $ %
mark332 #3
Posted 15 July 2013 - 05:21 PM
Thanks for your quick reply, I'll test it out tomorow ;)/>/> :D/>/>

Ok, now my Problem is: "strings:3: String expected, got nil"

I'm calling your function, like the old one, please tell me, if I have to call it in another way. ;)/>
Sharidan #4
Posted 16 July 2013 - 10:45 AM
LBP already posted a workable function, but I figured I'd post you a copy of one of the multipurpose split functions listed on the lua reference site.


function split(pString, delim)
  local t = {};
  local fpat = "(.-)"..delim;
  local last_end = 1;
  local s, e, cap = pString:find(fpat, 1);
  while s do
    if (s ~= 1 or cap ~= "") then
      table.insert(t, cap);
    end
    last_end = e + 1;
    s, e, cap = pString:find(fpat, last_end);
  end
  if (last_end <= #pString) then
    cap = pString:sub(last_end);
    table.insert(t, cap);
  end
  return t;
end;

I have used this to split up long paths so I could truncate them.
Usage example:

local folderNames = split("/user/myName/yourName/hisName/herName/theDogsName/goldFishName", "/")

This returns a table with only the names listed.
Your original piece of code is roughly the same, but doesnt include the "(.-)" pattern matching. Hope this helps you.
theoriginalbit #5
Posted 16 July 2013 - 11:30 AM
Also in addition to what LBPHacker posted, this is a common split function using patterns


local function split( str, patt )
  local t = {}
  for s in str:gmatch( "[^"..patt.."]+" ) do
    t[#t+1] = s
  end
  return t
end

Using the above function you could just then do


local vals = split( "some,csv,string", "," )

instead of

local vals = split( "some,csv,string", "(.-)," )

All other rules still apply from LBP's version.
mark332 #6
Posted 16 July 2013 - 04:21 PM
Ok, thanks for your answers, I'll test it out, tomorow. (again ;)/> )