1

I only found this related to what I am looking for: Split string by count of characters but it is not useful for what I mean.

I have a string variable, which is an ammount of 3 numbers (can be from 000 to 999). I need to separate each of the numbers (characters) and get them into a table.

I am programming for a game mod which uses lua, and it has some extra functions. If you could help me to make it using: http://wiki.multitheftauto.com/wiki/Split would be amazing, but any other way is ok too.

Thanks in advance

Community
  • 1
  • 1
Karevan
  • 139
  • 1
  • 16

2 Answers2

4

Corrected to what the OP wanted to ask:

To just split a 3-digit number in 3 numbers, that's even easier:

s='429'
c1,c2,c3=s:match('(%d)(%d)(%d)')
t={tonumber(c1),tonumber(c2),tonumber(c3)}

The answer to "How do I split a long string composed of 3 digit numbers":

This is trivial. You might take a look at the gmatch function in the reference manual:

s="123456789"
res={}
for num in s:gmatch('%d%d%d') do
    res[#res+1]=tonumber(num)
end

or if you don't like looping:

res={}
s:gsub('%d%d%d',function(n)res[#res+1]=tonumber(n)end)
jpjacobs
  • 9,359
  • 36
  • 45
  • First code didnt worked, second one is exactly what I needed. Accepted your answer, thanks : ) – Karevan Jul 13 '12 at 14:34
  • Weird. Here they do exactly the same. – jpjacobs Jul 13 '12 at 14:38
  • well, I still have a problem, first index of the table works ok if the string is lower than 009, else it equals the full string :s and the other values are nil ones – Karevan Jul 13 '12 at 14:40
  • Okay, everything fine now, I just had to use :gmatch('%d') instead of :gmatch('%d%d%d') since my string is 3 chars only. Sorry for me being stupid. Again thanks – Karevan Jul 13 '12 at 14:45
  • Right, now I see the problem ... I thought you wanted something to split a long long string of 3-digit numbers into the respective numbers :) – jpjacobs Jul 14 '12 at 08:22
1

I was looking for something like this, but avoiding looping - and hopefully having it as one-liner. Eventually, I found this example from lua-users wiki: Split Join:

fields = {str:match((str:gsub("[^"..sep.."]*"..sep, "([^"..sep.."]*)"..sep)))}

... which is exactly the kind of syntax I'd like - one liner, returns a table - except, I don't really understand what is going on :/ Still, after some poking about, I managed to find the right syntax to split into characters with this idiom, which apparently is:

fields = { str:match( (str:gsub(".", "(.)")) ) }

I guess, what happens is that gsub basically puts parenthesis '(.)' around each character '.' - so that match would consider those as a separate match unit, and "extract" them as separate units as well... But I still don't get why is there extra pair of parenthesis around the str:gsub(".", "(.)") piece.

I tested this with Lua5.1:

str = "a - b - c"
fields = { str:match( (str:gsub(".", "(.)")) ) }
print(table_print(fields))

... where table_print is from lua-users wiki: Table Serialization; and this code prints:

"a"
" "
"-"
" "
"b"
" "
"-"
" "
"c"
sdaau
  • 36,975
  • 46
  • 198
  • 278
  • The extra parenthesis are needed because `gsub` returns two values but `match` should only get the first. Also `str:gsub(".", "(.)")` *replaces* every character (matched by `.`) with the literal string `(.)`. So `("foo"):gsub(".", "(.)")` returns `"(.)(.)(.)"` and 3. `("foo"):match("(.)(.)(.)")` then returns `"f", "o", "o"`. – Lucas Jan 03 '23 at 16:02
  • I get an error "too many captures" if my string is longer than 32 characters. – Lucas Jan 03 '23 at 16:07