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

Help with string handling

Started by Matplotlib, 25 August 2015 - 07:31 PM
Matplotlib #1
Posted 25 August 2015 - 09:31 PM
Hello there !
I'd like to know if something is possible in computercraft (CraftOS 1.7) and then how. First, a bit of story !

I prompt the user a command, that can be like this :

craft <item [matter]> [number]
get <item,block> <number>
emptyChest
Here are some examples :

"craft pickaxe iron"
"craft sword diamond 2"
"craft piston 5"
"get cobblestone 64"
"get redstone 128"
"emptyChest"
The final goal is via rednet, sending this command to a crafty turtle so it gets everything in the chests, it crafts the thing(s) if needed, and then brings everything in a chest.
But before this, I have a problem with the command itself : how to split the different n parts of the command into n different srings ? Also, I'd like to know the number of substrings…
With those examples, it would do :

"craft pickaxe iron" > "craft", "pickaxe", "iron", 3
"craft sword diamond 2" > "craft", "sword", "diamond", "2", 4
"craft piston 5" > "craft", "piston", "5", 3
"get cobblestone 64" > "get", "cobblestone", "64", 3
"get redstone 128" > "get", "redstone", "128", 3
"emptyChest" > "emptyChest", 1

Thanks in advance !
Lyqyd #2
Posted 26 August 2015 - 01:03 AM
The best way to do this is to use string.gmatch, using a pattern that matches non-whitespace characters, like "(%S+)". If you put the matches into a table, you can also easily get the total number of arguments.
Link149 #3
Posted 26 August 2015 - 01:29 AM
I'd suggest using string.gmatch together with the "%w+" pattern, in this case.
"%w" will match any alphanumeric character (any letter or number).

Append a '+' to "%w" and gmatch will now match sequences of one or more alphanumeric characters.

Here's a little example:

local str = "craft pickaxe iron 2"
local tTokens = {}

for match in str:gmatch("%w+") do
  table.insert(tTokens, match)
end

This piece of code will match every word of the string "str" and put them in a table called "tTokens".
You can use the function table.maxn(), or the expression #tTokens to get the number of tokens, or words contained in the tTokens table.
Edited on 25 August 2015 - 11:30 PM
HPWebcamAble #4
Posted 26 August 2015 - 02:31 AM
You can use this simple 'split' function to separate the arguments:

local function split(sString,sep)
  if sep == nil then sep = "%s" end
  local t={}
  for str in string.gmatch(sString, "([^"..sep.."]+)") do
	table.insert(t,str)
  end
  return t
end

Example usage:

local str = "This is an example"

local args = split( str , " " ) --# Tells it each argument is separated with a space (" ")

print( args ) --#> { "This" , "is , "an" , "example" }

Tables will play a large part in this project, you'll want to read up on them if aren't familiar with them.
http://www.lua.org/pil/2.5.html
Edited on 26 August 2015 - 07:26 PM
Matplotlib #5
Posted 26 August 2015 - 09:19 AM
Well… This is absolutely wonderful >^.^<
Thanks !
CoderPuppy #6
Posted 26 August 2015 - 03:16 PM
Here's a little example:

for match in str:gmatch("%w+") do
That errors with 'attempt to call string'

Are you sure you wrote gmatch not match when you tried it (gmatch returns a function that each time it's called it returns a new match, match just returns the match)?
Edited on 26 August 2015 - 01:17 PM
HPWebcamAble #7
Posted 26 August 2015 - 09:25 PM
Here's a little example:

for match in str:gmatch("%w+") do
That errors with 'attempt to call string'

Are you sure you wrote gmatch not match when you tried it?

Oops, I did use match. Nice catch! Removed that part from my first post