Jump to content




Split a string in two variables


  • You cannot reply to this topic
21 replies to this topic

#1 Ermans

  • Members
  • 5 posts

Posted 10 February 2013 - 12:37 PM

Title: Split a string in two variables


Hello, this is my question:
If I have a string with this formatting :

message="/add a_number"

How I can capture the code from " / " to space and the code after the space and assign two variable?

Thanks for help and sorry if the my english is bad, because I not speak (and I not write) english very well.

#2 Kingdaro

    The Doctor

  • Members
  • 1,636 posts
  • Location'MURICA

Posted 10 February 2013 - 12:50 PM

You can use gmatch and capture all non-space characters.

local message = "/add a_number"
local words = {}

for word in message:gmatch('%S+') do
  table.insert(words, word)
  print(word)
end

For these purposes, the script prints every word it finds. The output would be this:
/add
a_number


#3 Eric

  • Members
  • 92 posts
  • LocationUK

Posted 10 February 2013 - 01:41 PM

local command, args = message:match('/(.-) (.+)')


#4 Kingdaro

    The Doctor

  • Members
  • 1,636 posts
  • Location'MURICA

Posted 10 February 2013 - 01:45 PM

View PostEric, on 10 February 2013 - 01:41 PM, said:

local command, args = message:match('/(.-) (.+)')
Doesn't work well with more than one argument, but it would work if OP only wants one argument allowed.

#5 Doyle3694

  • Members
  • 815 posts

Posted 10 February 2013 - 03:33 PM

Also, just to clearify because I think you are new to lua, and they are using :'s. : will enter the table it's called from as the first argument, so message:gmatch('%S+') would be the same as string.gmatch(message,'%S+').

Just a clarification, not really connected to your first question, but I know it bugged me when I didn't know what it ment :P

#6 Ermans

  • Members
  • 5 posts

Posted 10 February 2013 - 10:42 PM

Thanks at all for fast reply.
But if I have this code:
message-size-color
example:
Hello World-5-red

How I split that in 3 variable?
Same Kingdaro's process?

#7 Eric

  • Members
  • 92 posts
  • LocationUK

Posted 10 February 2013 - 11:47 PM

local message, size, color = message:match('/(.+)-(.-)-(.-)')


#8 Kingdaro

    The Doctor

  • Members
  • 1,636 posts
  • Location'MURICA

Posted 11 February 2013 - 06:13 AM

View PostEric, on 10 February 2013 - 11:47 PM, said:

local message, size, color = message:match('/(.+)-(.-)-(.-)')
The minus symbol needs to be escaped.

local message, size, color = message:match('/(.+)%-(.-)%-(.-)')


#9 Ermans

  • Members
  • 5 posts

Posted 11 February 2013 - 06:17 AM

View PostKingdaro, on 10 February 2013 - 12:50 PM, said:

You can use gmatch and capture all non-space characters.

local message = "/add a_number"
local words = {}

for word in message:gmatch('%S+') do
  table.insert(words, word)
  print(word)
end

For these purposes, the script prints every word it finds. The output would be this:
/add
a_number

Thanks, it works!

Now I want split a variable like this:
message-size-color
But the code of Eric don't work :(


So I want write a string that contain three variable (string, number, string) , but i think the hyphen isn't good way to do this.
How I can do it fine?

#10 Djerun

  • Members
  • 21 posts

Posted 11 February 2013 - 10:42 AM

you could use string.find to search for the position of your dividing character, then use string.sub to save the part before it to a variable or table (append the empty string to it (.."") to make sure new memory is allocated for it) then use string.sub to save the part after the divider to the same variable you were reading from again make sure new memory is allocated for it by appending the empty string.
repeat this until your variable holding the message does not contain the divider anymore. it now holds the last part of your message


I wrote a little testprogram for this
local argv = { ... }
local msg = argv[1]
local Table = {}
local index = 1
local divider = "-"
if msg ~= nil then
  local pos = string.find(msg, divider)

  while pos ~= nil do
	Table[index] = string.sub(msg, 1, pos - 1)..""
	index = index + 1
	msg = string.sub(msg, pos + 1)
	pos = string.find(msg, divider)
  end

  Table[index] = msg

  for i = 1, index do
	print(Table[i])
  end

end
and after confirming it working by the program logic logic tested it with
testprog test-1-2-3
testprog test-1-2-3-
testprog -
testprog
the first works just fine
the second creates an empty string in the last table entry
the third creates a table with two empty entries
the fourth does nothing (obviously)

#11 Kingdaro

    The Doctor

  • Members
  • 1,636 posts
  • Location'MURICA

Posted 11 February 2013 - 10:47 AM

Really, guys. Just use gmatch.

local message = "message-size-color"
local words = {}

for word in message:gmatch('[^%-]+') do
  table.insert(words, word)
end

print(words[1]) --> message
print(words[2]) --> size
print(words[3]) --> color

Though eric's method works fine, as long as you only need three arguments, and as long as the dashes are escaped in the match string.

local message, size, color = message:match('(.+)%-(.+)%-(.+)')


#12 Djerun

  • Members
  • 21 posts

Posted 11 February 2013 - 11:07 AM

gmatch needs knowledge about regular expressions (which every programmer should have because they are really handy) and which extra rules apply to them in lua (at least here) which certainly not everyone starting out with CC has or is willing to learn.

if you solve a problem with regular expressions you should at least link to somewhere someone could learn more about them in case he can learn more about them and doesn't have to ask a new question every time that knowledge could be applied (ofc those who don't want to know it simply wouldn't read it and ask again with the next problem)

and since this is a rather small problem since only one character needs to be detected a more basic solution doesn't hurt (unless CC generates an insane amount of overhead) and also may teach one more about strings (which is even more important that learning about regexpr)

#13 Kingdaro

    The Doctor

  • Members
  • 1,636 posts
  • Location'MURICA

Posted 11 February 2013 - 11:33 AM

OP didn't specifically ask for an easy-to-understand overly-complicated solution, he/she just wanted a valid answer to the problem, and with that in mind, I provided the most efficient solution that would take the least amount of time to type, and probably is most logical.

Also, Lua patterns aren't regular expressions. If you insist the OP should learn more, here's a link about lua patterns.

Reference Manual:
http://www.lua.org/m...nual.html#5.4.1

And in lua-users since that's usually easier to understand:
http://lua-users.org...atternsTutorial

#14 Ermans

  • Members
  • 5 posts

Posted 11 February 2013 - 11:34 AM

Thanks at all ;)
Now it works!

#15 Djerun

  • Members
  • 21 posts

Posted 11 February 2013 - 01:03 PM

View PostKingdaro, on 11 February 2013 - 11:33 AM, said:

OP didn't specifically ask for an easy-to-understand overly-complicated solution, he/she just wanted a valid answer to the problem, and with that in mind, I provided the most efficient solution that would take the least amount of time to type, and probably is most logical.
what exactly do you think gmatch does behind the scenes?

#16 Kingdaro

    The Doctor

  • Members
  • 1,636 posts
  • Location'MURICA

Posted 11 February 2013 - 01:27 PM

View PostDjerun, on 11 February 2013 - 01:03 PM, said:

what exactly do you think gmatch does behind the scenes?
I hate it when people say things like this. It's the same logic as manually maintaining coroutines yourself instead of using the parallel API, because that's what parallel does behind the scenes, but it's there for a reason. Why do in 20 lines what you could do in 3?

Plus, if there's a better solution, fuck all if it's too difficult for you to use. Just learn about it instead of sticking with the same old outdated primitive methods.

#17 ChunLing

  • Members
  • 2,027 posts

Posted 12 February 2013 - 11:48 AM

I think that, behind the scenes, gmatch is written in C (or Java, depending on implementation) and is crazy faster than anything equivalent you could write in Lua without using gmatch.

It's well worth knowing how to use it.

#18 Djerun

  • Members
  • 21 posts

Posted 12 February 2013 - 05:43 PM

Quote

I think that, behind the scenes, gmatch is written in C (or Java, depending on implementation) and is crazy faster than anything equivalent you could write in Lua without using gmatch.
that definetly depends on how exactly the lua is sandboxed but it's most likely faster(because it's interpreted and gmatch most likely uses a compiled functionality)
most code for compiled languages is translated to C but it really depends on the compilers quality. just because something is in C it doesn't mean its fast (being compiled over being interpreted most times means compiled is faster though)

Quote

It's well worth knowing how to use it.
and I did not doubt that

Quote

I hate it when people say things like this. It's the same logic as manually maintaining coroutines yourself instead of using the parallel API, because that's what parallel does behind the scenes, but it's there for a reason. Why do in 20 lines what you could do in 3?

Plus, if there's a better solution, fuck all if it's too difficult for you to use. Just learn about it instead of sticking with the same old outdated primitive methods.
for a, b, c, d in string.gmatch("TUFS", "^(%a)(%u)(%x)(%w)$") do print(d, a, c, b) end


#19 Eric

  • Members
  • 92 posts
  • LocationUK

Posted 12 February 2013 - 09:10 PM

CC's gmatch is in bios.lua (for reasons I don't fully understand), and falls back on :find (which is java-side)

#20 ChunLing

  • Members
  • 2,027 posts

Posted 13 February 2013 - 12:24 PM

What? Where? Who?





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users